为什么在执行此过程而不是EPrivilege - Privileged instruction
时会收到“Access Violation
”?
{$Warnings OFF}
procedure TFrmMyTest.mnuCrashMeClick(Sender: TObject);
var t: TStringList;
begin
FreeAndNil(t);
end;
{$Warnings ON}
我知道我试图释放一个随机指向内存的对象。但我希望获得访问冲突而不是“特权指令”。
(不要担心我不打算在真实程序中使用上面的代码。)
答案 0 :(得分:9)
FreeAndNil
调用非虚方法Free
。首先检查nil
(变量可能不是nil
),然后调用虚拟析构函数Destroy
。
调用虚方法意味着查看对象的开头以获取虚方法表(VMT)。这可能会导致访问冲突。但是如果对象在已分配的内存中,它将返回一个未定义的指针作为VMT。
接下来,在距离VMT的某个偏移处读取指针大小的值。这再一次可以抛出访问冲突或返回一个未定义的指针。
最后执行此指针指向的内存。如果碰巧包含无效代码,则会得到一些无效指令异常的变体。
答案 1 :(得分:3)
有时您会遇到访问冲突,有时您会得到EPrivilege
,毫无疑问还有其他失败模式。甚至有时候代码看起来会起作用,崩溃会在以后发生。这一切都取决于您在t
上调用Free
时的价值。