Linux 中的 easy Delphi 程序中的分段错误 - Windows 没问题

Segmentation fault in easy Delphi program in Linux - Windows is fine

我有这个简单的程序,用 Delphi 10.2 编写,运行 在 Windows 上运行良好,但在 Linux.

上崩溃

其实质就是使用的class在其析构函数中有要执行的代码

type
  Kwak = class
  public
    index: integer;
    constructor Create(index:integer);
    destructor Free;
  end;

constructor Kwak.Create(index:integer);
begin
  self.index := index;
  writeln('Welcome Kwak '+inttostr(index));
end;

destructor Kwak.Free;
begin
  writeln('Bye Kwak '+inttostr(index));
end;

如果我在调用过程中使用它,比如这个:

procedure myProc1;
var 
  myKwak:Kwak;
begin
  myKwak := Kwak.Create(15);
  myKwak.Free;
end;

这在 Windows 上运行良好,但在 myKwak 离开范围时在 Linux 上导致分段错误(在 myProc1 中遇到 end ).

我猜这一切都与 Linux 编译器上的自动引用计数有关。

如果我使用FreeAndNil(),程序不会崩溃,但也不会调用析构函数。

什么是优雅的解决方案?

请告诉我你的建议。

destructor Free; // <-- WRONG!

这是错误的。正确的析构函数称为 Destroy(),它在 TObject 中是 virtual,因此您需要在派生 类:

override
type 
  Kwak = class
  public
    index: integer;
    constructor Create(index:integer);
    destructor Destroy; override;
  end;

constructor Kwak.Create(index:integer);
begin
  inherited Create;
  self.index := index;
  writeln('Welcome Kwak '+inttostr(index));
end;

destructor Kwak.Destroy;
begin
  writeln('Bye Kwak '+inttostr(index));
  inherited;
end;

在非 ARC 系统上,TObject.Free() 是一个非虚拟实例方法,如果 Self 不是 nil,则调用 Destroy() 析构函数。

在 ARC 系统上,编译器会自动将所有对 Free() 的调用替换为 nil 赋值,从而减少对象的引用计数。这样可以在 ARC 和非 ARC 系统上使用具有相似语义的相同代码。对象的 Destroy() 析构函数在其引用计数降至 0 时被调用。