为什么我会得到一个错误的 HeapTrc 签名?

Why do I get a Wrong signature with HeapTrc?

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

您将 FClass3 转换为 TClass2。但是你实例化了TClass1。因此,演员阵容不正确,这可以解释错误。从本质上讲,您对编译器撒了谎,它进行了报复。

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