在调用类析构函数之前,Delphi类变量超出范围

时间:2013-10-12 09:50:23

标签: delphi class variables memory-leaks destructor

在类变量中使用动态数组来存储在调用类析构函数时需要释放的对象不起作用。

在调用类析构函数之前,数组似乎已经超出了范围并且已经被处理掉了。 这是设计吗?

在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;

2 个答案:

答案 0 :(得分:5)

类析构函数被称为AFTER单元终结,因此这意味着在调用类析构函数时,Array不再存在。在单元最终确定时,RTL会清除所有管理变量。最后它应该没关系,因为它实际上不是泄漏。

Allen Bauer提供了有关类构造函数/析构函数here的更多信息。

修改

显然这是design

答案 1 :(得分:1)

这个"设计"已经修好了。 Delphi 10 Seattle的行为就像每个人(包括你和我)所期望的那样 - 它在类析构函数之后释放了引用计数的类变量。

可能Embarcadero的某个人终于意识到反过来绝对不是很酷,特别是在移动平台上使用ARC:D

请参阅:https://quality.embarcadero.com/browse/RSP-11289