2011-08-16 20 views
3

私は、コードを以下の(I}はobjCurがフリーの前にnilでない確認していますこの無効なポインタはどこにありますか?

try 
    objCur.Free; 
Except on E:Exception do 
    begin 
    OutputDebugString(PChar('Exception '+E.Message)); 
    Assert(False); 
    end; 
end; 

それはこの例外メッセージを報告:。。

無効なポインタ操作をobjCurがTXX_TEAタイプです
objCur:TXX_TEA ; Iはコード

0123を下記たTXX_TEA.Destroyにおいて

内部破壊

例外の
...
エンド破壊:私は次のメッセージが表示さのDebugViewで

無効なポインタ操作

を私はobjCur.Free呼び出しを知っていますTXX_TEA.Destroyが、TXX_TEA.Destroyはエラーなしで実行されます。では、この無効なポインタ操作をどこでトレースする必要がありますか?

+3

'objCur'が非nilかどうかを確認するだけでは不十分です。実際、もしそれが* nilであれば、まったく問題はありませんでした。有効なオブジェクトを参照するかどうかをチェックする必要があります。これは実際にプログラムで確認できるものではありません。プログラムを分析して、変数に無効な参照があるようなバグがないことを確認する必要があります。 –

+0

私はobjCur.FreeがいつTXX_TEA.Destroyを最初に呼び出すのかを知りたいと思っています。それからそれ自身のプロパティを解放しますか? TXX_TEAでは、Allos、Allos [i] .xx = self.xxというプロパティが存在するため、 TXX_TEA.Destroyでは、Allos.Freeが呼び出されます。 objCurがそのxxプロパティを解放したときに既に解放されているかどうかは疑問です – spspli

答えて

9

無効なポインタ操作は、メモリマネージャがメモリマネージャに属していないメモリを解放するよう要求された場合に発生します。

オブジェクトのメモリは、一番外側のデストラクターが呼び出し元に戻る直前に解放されます。この場合の呼び出し元はTObject.Freeです。 inheritedを呼び出すと、オブジェクトのメモリは解放されません。これは、コンパイラが最も外側の呼び出しではないことをコンパイラが認識しているためです。

実際には存在しないオブジェクトを解放していますが、この想定されるオブジェクトのメモリの内容は、オブジェクトのフィールドをクリーンアップするデストラクタ内のコードがクラッシュするほど有効であるように見えます。デストラクタが実行を終了し、オブジェクトが解放され、メモリマネージャがアドレスが現在割り当てられているものを参照していないことを検出した場合のみです。

3

まだ参照があり、そのコードを使用してその参照を使用してオブジェクトがアクセスされた後にアクセスする可能性が非常に高いです。これは、オブジェクト参照またはインタフェース参照(nilでないインタフェースrefsは、スコープの最後に_Releaseを呼び出す)です。

本当に何が原因なのかを調べるにはもっとコードを見なければなりません。

+0

+1インタフェース参照カウント –

+0

オブジェクト参照またはインターフェイス参照がどこにあるのかを調べる一般的な方法はありますか? – spspli

+1

RTLおよびVCLデバッグユニットを使用したデバッグは、実際に何が起きているのか、またどこがうまくいかないのかを見つけるのに役立ちます。また、例外が発生する前にスタックトレース*を見てください。 –

6

無効なポインタ何かを解放しようとする操作は、ほとんどの場合、既に解放されていることを意味します。どこから探したいのか、最も簡単な方法は、SourceForgeからFastMMのフルバージョンを入手することです。ドキュメントを読むと、プロジェクトに追加する方法と、FullDebugModeをオンにする方法が表示されます。 FullDebugModeをオンにすると、すでに解放されているものを解放しようとすると、オブジェクトが最初に解放されたときのスタックトレースなどのダイアログボックスが表示され、プログラムが中断されます。それはエラーを追跡するのに役立ちます。

関連する問題