try…finally for multiple objects

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.

This entry was posted in Tips and Tricks and tagged . Bookmark the permalink.