Linux中简单的Delphi程序中的分段错误-Windows很好

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

本质是所使用的类具有要在其析构函数中执行的代码。

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 上运行良好,但在 Linux 上myKwak离开范围时会导致分段错误(在end中遇到myProc1)。

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

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

什么是优雅的解决方案?

  • Free我的程序中有很多这样的。当然,将Free代码转移到其他地方是可能的,但我希望它更优雅。
  • 程序需要在 Windows 中编译回 XE2,在 10.2 上的 Linux 上。我读到 10.3 遗漏了 ARC,这可能会解决问题,但 10.3 的成本很高。
  • 需要的程序更改和{$IFDEF ...}指令最好最小化。

请告诉我你的建议。

回答

destructor Free; // <-- WRONG!

这是错误的。正确的析构函数被调用Destroy(),它virtual在,TObject所以你需要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()是一个非虚拟实例方法,Destroy()如果Self不是,则调用析构函数nil

在ARC系统,编译器默默地替换所有来电Free()nil分配,递减对象的引用计数。因此,相同的代码可以在 ARC 和非 ARC 系统上以相似的语义使用。对象的Destroy()析构函数在其引用计数下降到 0 时被调用。


以上是Linux中简单的Delphi程序中的分段错误-Windows很好的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>