Today I found another common mistake. Someone used more than one object and has to free them.
var pObject1: TMyObject1; pObject2: TMyObject2; begin pObject1 := TMyObject1.Create; try pObject1.DoSomething; pObject2 := TMyObject2.Create; try pObject2.DoSomethingElse; finally pObject2.Free; end; finally pObject1.Free; end; end;
Instead of nested try…finally blocks it is easier and more readable to do the same with one try…finally block
var pObject1: TMyObject1; pObject2: TMyObject2; begin pObject2 := nil; pObject1 := nil; try pObject1 := TMyObject1.Create; pObject1.DoSomething; pObject2 := TMyObject2.Create; pObject2.DoSomethingElse; finally pObject1.Free; pObject2.Free; end; end;
This solution can still be improved. The first object can be created outside the try…finally block
var pObject1: TMyObject1; pObject2: TMyObject2; begin pObject2 := nil; pObject1 := TMyObject1.Create; try pObject1.DoSomething; pObject2 := TMyObject2.Create; pObject2.DoSomethingElse; finally pObject1.Free; pObject2.Free; end; end;
Please remember that all variables that are freed in the finally block must be initialized before the try statement.
I guess that most of you know this practice for many years but there are still people around who don’t.