Today I found another common mistake. Someone used more than one object and has to free them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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.