我最多简化了以下代码,只显示我的问题。 当析构函数TClass3.Destroy完成时,FreeAndNil(FClass3)操作会导致问题并且程序停止。如果查看Heap.trc文件,我可以阅读
标记为$ 0000000001528FD0的内存无效
错误的签名$ 2951FD2D而不是5C063D8B
program Project_testFree;
{$mode objfpc}{$H+}
uses
sysutils;
type
TClass1 = class
private
protected
public
constructor Create;
end;
TClass2 = class(TClass1)
private
protected
FTClass2 : cardinal;
public
end;
TClass3 = class
private
protected
FClass3 : TClass1;
public
constructor Create;virtual;
destructor Destroy;override;
end;
TClass4 = class(TClass3)
private
function GetLocalClass2: TClass2;
protected
public
constructor Create;override;
destructor destroy;override;
property pClass2:TClass2 read GetLocalClass2;
end;
constructor TClass1.Create;
begin
inherited;
end;
constructor TClass3.Create;
begin
FClass3 := TClass1.create;
end;
destructor TClass3.Destroy;
begin
FreeAndNil(FClass3);
writeln('Destroy');
inherited Destroy;
end;
constructor TClass4.Create;
begin
inherited Create;
pClass2.FTClass2 := 1;
end;
destructor TClass4.destroy;
begin
inherited destroy;
end;
function TClass4.GetLocalClass2: TClass2;
begin
result := TClass2(FClass3);
end;
var
c:TClass4;
begin
if FileExists('heap.trc') then
DeleteFile('heap.trc');
SetHeapTraceOutput('heap.trc');
c:=TClass4.Create;
c.free;
end.
我使用Lazarus 1.6.2。 谢谢你的帮助。
答案 0 :(得分:3)
您将FClass3
投射为TClass2
。但是你实例化了TClass1
。因此,演员表是不正确的,这可以解释错误。从本质上讲,你欺骗了编译器并且它报复了它。
如果您使用as
使用了已检查的强制转换,则会引发运行时错误。