One little thingy

try...finally

try...except

BeforeDestruction

Where does it leak?

FreeInstance

FreeInstance

BeforeDestruction

FreeInstance

BeforeDestruction

But, I have try...finally

BeforeDestruction

BeforeDestruction

BeforeDestruction

var Broken: TBroken; begin Broken := TBroken.Create; try finally Broken.Free; end; end;

var Broken: IBroken; begin Broken := TBrokenAutomatic.Create; end;

Please, don't

try...except

destructor TFoo.Destroy; begin FBar.Free; inherited; end;

FBar

TFoo

TBar

try...except

FBar.Free

TBar

TBar

TFoo

TFoo

Delphi is exception safe language. That means well written code can recover from the most horrible exceptions, including the dreaded out of memory error, and continue running in a perfectly operational state - as if nothing bad happened. Of course, that is a feature that Delphi provides, but your code and application eventually must determine logic at which point raised exception is recoverable and at which point it is not.For instance, if you allow user to open some external file for further processing and your code trips on out of memory exception because the file is too large to process, you can fully recover from such event, show error message to the user "Sorry, selected file is too big" and application can merrily continue working. On the other hand if you trigger out of memory error during some operation your application absolutely must be able to perform, you can decide that the best course of action is terminating the application - after you show appropriate error message and perform whatever shutdown procedure is required.Focus of this post is not teaching you how to write exception cleaning and handling code and how and when to useandblocks.It is about pointing to one often forgotten and ignored fact that can crush all your exception handling efforts:Particulary, that means themethod - and destructors themselves - must never ever allow exceptions to escape them. Any escaping exception there will always cause memory leak. Period.Unhandled exception in any destructor will not only break calling inherited destructors chain (if there are any), but more importantly itskip callingmethod that is automatically called after the destructor chain and is responsible for cleaning up instance managed fields and releasing its memory allocated on the heap. Ifdoes not run, your code will leak that object instance's memory.Same applies to themethod - unhandled exception there will skip calling the whole destructor chain as well asProper handling of any exceptions insidemethod or destructors implies that you must make sure that all code that is responsible for any kind of cleanup, including calling inherited methods, that absolutely must be executed is executed during that exception handling process.No amount of dancing around broken destructors (or) will fix the memory leak. That is just wishfull thinking. The only way to fully and properly solve such leaks is to fix broken destructors (or) from within.Even code using interfaces and automatic memory management will cause memory leaks if exceptions break destruction process.Assuming that following classes cause unhandled exceptions inor in any of the destructors all following code will result with memory leaks.If you are tempted to go around your code eating up all exceptions withblocks in every destructor you have ever written, then please don't.Not every single line of code is exception prone. You just have to protect code that really can cause an exception and not all of it.Following destructor code is perfectly fine. No need to handle any exceptions there.Of course, ifdestructor is broken thendestructor will also be broken, but the proper place to handle potential exception is indestructor itself. Addingcode aroundwill accomplish absolutely nothing because ifdestructor is broken,object instance will leak regardless. Yes, eating up exception indestructor would at least prevent leaking ofinstance, but if it is broken does it really matter how much?