Why is Destroy not called?
Asked Answered
G

2

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;
Gendarmerie answered 25/5, 2012 at 14:11 Comment(3)
destructor Destroy(); override; Oops.Gendarmerie
Didn't the compiler warning you about your code? It should have. Something about hiding a virtual method of the same name.Wendelina
Never ignore a warning. Ignore a warning is ignoring a bug, in many cases!Lilt
B
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.

Bray answered 25/5, 2012 at 14:18 Comment(2)
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.Gendarmerie
Right, Steve. Override goes with virtual methods. TObject.Create is not virtual, so you can't override it. TObject.Destroy is virtual.Wendelina
A
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.

Authorship answered 25/5, 2012 at 14:20 Comment(1)
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.Gendarmerie

© 2022 - 2024 — McMap. All rights reserved.