为什么我用HeapTrc获得错误的签名?

时间:2017-09-26 19:17:40

标签: lazarus

我最多简化了以下代码,只显示我的问题。 当析构函数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。 谢谢你的帮助。

1 个答案:

答案 0 :(得分:3)

您将FClass3投射为TClass2。但是你实例化了TClass1。因此,演员表是不正确的,这可以解释错误。从本质上讲,你欺骗了编译器并且它报复了它。

如果您使用as使用了已检查的强制转换,则会引发运行时错误。