You need to enable JavaScript to run this app. Delphi简单程序Windows正常运行Linux报Segmentation fault问题求解
优惠活动
大模型
产品
解决方案
定价
更多

Delphi简单程序Windows正常运行Linux报Segmentation fault问题求解

问题根因

崩溃的核心是错误重写了TObject的原生Free方法,和Delphi ARC机制的内存管理逻辑冲突:

  • 非ARC平台(Windows下的Delphi原生编译)的TObject.Free逻辑是判断对象不为空时调用Destroy析构,你自行重写Free写入析构逻辑,在非ARC下能正常运行属于巧合,因为手动调用myKwak.Free之后没有其他操作访问该对象
  • Linux下Delphi 10.2启用了ARC机制:对象的内存释放由引用计数自动管理,你手动调用自定义的Free直接释放了对象内存,当函数执行完、myKwak变量离开作用域时,ARC会自动给该对象的引用计数减1,访问已经被释放的内存地址就触发段错误
  • 使用FreeAndNil没有崩溃也不触发析构的原因是:ARC下FreeAndNil会把对象引用置空,但你的析构逻辑写在了重写的Free里,而不是标准的Destroy方法中,所以不会执行

最优解决方案(改动极小,全平台兼容,无需额外编译指令)

步骤1:修正类的析构定义

把原本写在destructor Free;里的逻辑迁移到标准的destructor Destroy; override;中,移除自定义的Free析构,修改后的类代码如下:

type
  Kwak = class
  public
    index: integer;
    constructor Create(index:integer);
    destructor Destroy; override; // 使用标准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 Destroy; // 补充父类析构调用
end;

步骤2:无需修改业务层调用代码

你原有业务代码里的myKwak.Free调用完全不需要改动:

  • 非ARC平台下,原生TObject.Free会自动调用你重写的Destroy,运行逻辑和之前完全一致
  • ARC平台(Linux 10.2)下,Free会被编译器自动映射为减引用计数的操作,当引用计数归0时自动调用Destroy,无需额外处理
  • 已使用FreeAndNil的代码也完全兼容,ARC下也会正确触发析构逻辑

额外适配说明

如果你的代码中有大量子类也重写了Free方法,只需要批量把destructor Free;替换为destructor Destroy; override;,把inherited Free改为inherited Destroy即可,业务层的Free调用一行都不需要修改,完全兼容XE2到10.2全版本、Windows+Linux双平台,不需要添加任何{$IFDEF ...}编译指令。

内容的提问来源于stack exchange,提问作者JP Hendriks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 17:15:04