7

Given the following Delphi code, Foo is Free'd on FormClose, but TFoo.Destroy is not being called - and therefore Bar is not Free'd, leading to a memory leak?

Have I missed something here or shouldn't Foo.Free call Foo.Destroy at some point?

type
  TBar = class
  SomeInteger : integer;
end;

TFoo = class
  Bar : TBar;

  constructor Create();
  destructor Destroy();
end;

var
  Foo : TFoo;

implementation

constructor TFoo.Create;
begin
  Bar := TBar.Create;
  Bar.SomeInteger := 2;
end;

destructor TFoo.Destroy;
begin
  Bar.Free;
  Bar := nil;

  showmessage('Destroyed!');
end;

procedure TForm10.FormCreate(Sender: TObject);
begin
  Foo := TFoo.Create;

  showmessage('Foo created');
end;

procedure TForm10.FormDestroy(Sender: TObject);
begin
  Foo.Free;
  Foo := nil;
end;
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Steve Magness
  • 863
  • 14
  • 25

2 Answers2

26

You must mark the signature of destructor with override.

destructor Destroy(); override;

And you should have inherited at the end of the destructor. But since your class is not derived from anything other than TObject I suspect that doesn't matter.

RobS
  • 3,807
  • 27
  • 34
  • Seems we worked this out at the same time... Answer will be accepted when I'm allowed to! I thought I had tried override, but I put override on Create too and that gives a compilation error. – Steve Magness May 25 '12 at 14:21
  • 1
    Right, Steve. `Override` goes with virtual methods. `TObject.Create` is not virtual, so you can't override it. `TObject.Destroy` *is* virtual. – Rob Kennedy May 25 '12 at 15:17
11

Destroy is virtual, and therefore you must override it in your descendant class.

TFoo = class
  Bar : TBar;

  constructor Create();
  destructor Destroy(); override; // must add override here
end;

Without the override, your destructor is never called, and the base class one is instead.

Nick Hodges
  • 16,902
  • 11
  • 68
  • 130
  • 3
    Thanks, got there in the end. As always it was part of a much larger project and couldn't work out what was going on. Funnily enough, simplifying the problem made the problem... simpler. – Steve Magness May 25 '12 at 14:24