Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi class variable going out of scope before class destructor is called

Using dynamic array in a class variable to store objects that need to be freed when the class destructor is called does not work.

The array seems to have gone out of scope and already disposed of before the class destructor is called. Is this by design ?

Example tested in XE5:

type
  TLeakingObject = class
  public
    I : Integer;
  end;

  TTheLeakOwner = class
  public
    class var OutofScopeArray:array of TLeakingObject;
    procedure Add;
    class destructor Destroy;
  end;

procedure TestThis;
var LeakingTest : TTheLeakOwner;
begin
  LeakingTest := TTheLeakOwner.Create;
  try
    LeakingTest.Add;
  finally
    LeakingTest.DisposeOf;
  end;
end;

{ TTheLeakOwner }

procedure TTheLeakOwner.Add;
begin
  setlength(OutofScopeArray, length(OutofScopeArray) + 1);
  OutofScopeArray[length(OutofScopeArray) - 1] := TLeakingObject.Create;
end;

class destructor TTheLeakOwner.Destroy;
var I: Integer;
begin
  // Length(OutofScopeArray) always = 0, gone out of scope before class destructor ??
  for I := 0 to Length(OutofScopeArray) - 1 do
    FreeAndNil(OutofScopeArray[i]);
end;
like image 921
jong Avatar asked Oct 12 '13 09:10

jong


1 Answers

The class destructor is called AFTER unit finalization so this means that the Array no longer exists at the time the class destructor is called. At unit finalization all managed variables are cleaned up by the RTL. In the end it should not matter because it is not really a leak.

Allen Bauer gives some more info about class constructors/destructors here.

EDIT

Apparently this is by design

like image 170
whosrdaddy Avatar answered Sep 30 '22 14:09

whosrdaddy