Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Destroy not called?

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;
like image 668
Steve Magness Avatar asked May 25 '12 14:05

Steve Magness


2 Answers

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.

like image 111
RobS Avatar answered Nov 15 '22 02:11

RobS


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.

like image 31
Nick Hodges Avatar answered Nov 15 '22 00:11

Nick Hodges