为什么释放坏对象指针抛出EPrivilege而不是EAccessViolation?

时间:2012-01-22 17:33:18

标签: delphi delphi-xe access-violation

为什么在执行此过程而不是EPrivilege - Privileged instruction时会收到“Access Violation”?

{$Warnings OFF}
procedure TFrmMyTest.mnuCrashMeClick(Sender: TObject);
var t: TStringList;
begin
 FreeAndNil(t);
end;
{$Warnings ON}

我知道我试图释放一个随机指向内存的对象。但我希望获得访问冲突而不是“特权指令”。

(不要担心我不打算在真实程序中使用上面的代码。)

2 个答案:

答案 0 :(得分:9)

FreeAndNil调用非虚方法Free。首先检查nil(变量可能不是nil),然后调用虚拟析构函数Destroy

调用虚方法意味着查看对象的开头以获取虚方法表(VMT)。这可能会导致访问冲突。但是如果对象在已分配的内存中,它将返回一个未定义的指针作为VMT。

接下来,在距离VMT的某个偏移处读取指针大小的值。这再一次可以抛出访问冲突或返回一个未定义的指针。

最后执行此指针指向的内存。如果碰巧包含无效代码,则会得到一些无效指令异常的变体。

答案 1 :(得分:3)

有时您会遇到访问冲突,有时您会得到EPrivilege,毫无疑问还有其他失败模式。甚至有时候代码看起来会起作用,崩溃会在以后发生。这一切都取决于您在t上调用Free时的价值。