在以下示例中:
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()
调用OK,而第二个调用导致访问冲突错误?当我逐步执行代码时,第一个Dispose()
调用System._FreeMem()
,而第二个调用System._Dispose()
,但我不明白为什么会出现这种情况。我希望了解这种行为,以便知道何时可以安全地在nil
指针上调用Dispose()
。
1条答案
按热度按时间qacovj5a1#
我希望了解此行为,以便知道何时可以安全地在
nil
指针上调用Dispose()
。在
nil
指针 * 变量 * 上调用Dispose()
是绝对不能OK的。RTL期望变量指向使用New()
分配的有效内存,因此将无条件地尝试完成所指向的任何数据/对象。传入nil
指针变量将导致 * 未定义的行为 *,并且可能崩溃。Dispose(nil)
实际上是一个空操作,编译器知道nil
常量不可能指向需要终结的数据类型,所以它不需要调用System._Dispose()
,而是调用System._FreeMem()
(我不知道它为什么调用任何东西)。System._FreeMem()
允许nil
作为输入,它将退出而不做任何事情。然而,指针 * 变量 * 上的System._Dispose()
不允许nil
作为输入(并且从来没有)。