So this isn't from my code and it's not new code, but I couldn't help but wanting to know the answer, just to satisfy my own curiosity.

So this isn't from my code and it's not new code, but I couldn't help but wanting to know the answer, just to satisfy my own curiosity.

Consider the following code:

type
  TFoo = object
    s: string; 
    constructor Init;
    destructor Done; virtual;
  end;
  PFoo = ^TFoo;

  TDescendant = object(TFoo)
    s2: string; 
    constructor Init;
    destructor Done; virtual;
  end;
  PDescendant = ^TDescendant;

{ TFoo }
constructor TFoo.Init;
begin
  s := IntToStr(42);
end;
destructor TFoo.Done;
begin
  WriteLn(s);
end;


{ TDescendant }
constructor TDescendant.Init;
begin
  inherited Init;
  s2 := IntToStr(123);
end;
destructor TDescendant.Done;
begin
  WriteLn(s2);
  inherited Done;
end;

var
  f: PFoo;
begin
  ReportMemoryLeaksOnShutdown := True;
  f := New(PDescendant, Init);
  Dispose(f, Done);
end.

Running this leaks the "s2" member. Now, I never used these old-style "object" types much at all, so I don't know how they're supposed to work, and google ain't being helpful. So how is one supposed to prevent s2 from leaking?

Adding "Finalize(Self)" as the last call in the destructors does the trick, but is there a "proper" way besides manually clearing all the fields?

Comments