2012-01-22 8 views
2

Access Violationの代わりにこの手順を実行すると「EPrivilege - Privileged instruction」が表示されるのはなぜですか?なぜ悪いオブジェクトポインタを解放すると、EAccessViolationではなくEPrivilegeがスローされるのですか?

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

ランダムにメモリにポイントするオブジェクトを解放しようとしています。しかし、私はアクセス権違反があり、特権命令ではないと考えています。

(私は実際のプログラムでは、上記のコードを使用する予定がない心配しないでください。)

答えて

3

時にはあなたがアクセス違反を取得し、時にはあなたがEPrivilegeを取得し、疑いの余地の他のモードが存在しません失敗。そして、時にはコードが動作するように見え、クラッシュが後で起こります。それはFreeを呼び出すときにどんな値がtにあるかによって決まります。

9

FreeAndNilは、非仮想メソッドFreeを呼び出します。最初にnil(変数はnilではない可能性があります)をチェックしてから、仮想デストラクタDestroyを呼び出します。

仮想メソッドを呼び出すとは、オブジェクトの先頭を見て仮想メソッドテーブル(VMT)を取得することを意味します。これにより、アクセス違反が発生する可能性があります。しかし、オブジェクトが割り当てられたメモリ内にある場合、代わりに未定義のポインタをVMTとして返します。

次のポインタサイズ値は、VMTから一定のオフセットで読み取られます。これは、再度、アクセス違反をスローしたり、未定義のポインタを返すことがあります。

最後に、このポインタが指すメモリが実行されます。また、無効なコードが含まれていると、無効な命令例外が発生します。

関連する問題