You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

何时可安全调用Dispose处理nil指针?示例中两次调用为何结果不同?

Delphi中Dispose(nil)与Dispose(nil类型化指针)的行为差异解析

先看问题中的代码:

program DisposeProblem;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  Person = record
    name: string;
    age: Integer;
  end;

var
  p: ^Person;

begin
  p := nil;
  Dispose(nil); // OK
  Dispose(p); // AV
end.

为什么会出现两种不同的行为?

核心原因是Dispose是重载过程,编译器会根据传入参数的类型匹配不同的底层实现:

  • 当直接传入字面量nil时,编译器会将其识别为Pointer类型(无类型指针),匹配到接受Pointer参数的Dispose重载,最终调用System._FreeMem。而_FreeMem的逻辑本身允许传入nil——底层会直接跳过释放操作,所以不会报错。
  • 当传入类型化指针变量(比如示例中^Person类型的p),哪怕变量值是nil,编译器会匹配到对应类型指针的Dispose重载,最终调用System._Dispose。_Dispose的职责不仅是释放指针指向的内存,还要处理指针指向结构里的托管类型资源(比如示例中Person记录里的name是string类型,属于托管资源,需要先释放字符串本身的内存)。但此时指针是nil,_Dispose尝试访问nil指向的内存时,就会触发访问违规(AV)。

何时能安全用Dispose处理nil指针?

  • 无类型指针场景:如果是Pointer类型的变量(或直接传字面量nil),调用Dispose是安全的,因为底层走_FreeMem,天然兼容nil。
  • 类型化指针场景:只要是带有具体类型的指针(比如^Person、^Integer),哪怕变量值是nil,也绝对不能直接调用Dispose——必须先判断指针不为nil,再执行释放操作。因为这类Dispose需要访问指针指向的内容来清理内部托管资源,nil指针会导致内存访问错误。
  • 额外注意:类实例的Free方法本身兼容nil,但Dispose主要用于指针、记录这类非托管类型的资源释放,不要混淆两者的使用场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:40:26