11

私は欠陥をデバッグしており、それをオブジェクトの vtable ポインタに絞り込みました0xddddddddこの回答は、Win32 デバッグ ビルドが通常、デッド メモリまたは削除されたメモリをこの特別な値に設定することを示しています。

ポインター自体は有効に見えることに注意してください0xdddddddd

コードのスニペットを次に示します。

std::list<IMyObject*>::const_iterator it;
for (it = myObjects.begin(); it != myObjects.end(); ++it)
{
    IMyObject* pMyObject = *it;
    if (pMyObject == 0)
        continue;

    pMyObject->someMethod(); // Access violation     
}

アクセス違反の行でブレークして を監視すると、それ自体は有効なアドレス ( ) を持っていますが、メンバーは無効 ( )pMyObjectであることがわかります。pMyObject0x08ede388__vfptr0xdddddddd

いくつかのメモ:

  • これはシングル スレッド アプリケーションであるため、競合状態やミューテックスの問題ではない可能性が高いです。
  • オブジェクトにアクセスする前に、コールスタックのさらに上のオブジェクトを削除するなどの明らかな問題はないようです。
  • この問題は、Windows 2008 サーバーでのみ再現可能で、Windows 7 では再現できないようです。

これをさらにデバッグする方法について何か提案はありますか?

4

4 に答える 4

12

ポインターが解放された後、ポインターを使用しています。デストラクタのブレークポイントからスタック トレースを取得して、何が削除されているかを確認します。または、問題を回避するために shared_ptr<> を使用してください。

于 2011-04-19T07:42:26.057 に答える
1

プログラムを開始する場合は、オブジェクトを作成する場所にブレーク ポイントを置きます。次に、メモリ ブレーク ポイントを追加します。これは、メモリを上書きまたは削除すると発火します。まあ、または何らかの方法で変更します。

メモリが上書きされていない場合、オブジェクトは正しく見えますが、vtable はコンパイラの仕様に依存していない可能性があります。

継承を使用している場合は、サイズの問題になる可能性もあります。何らかの種類のバケット メモリを使用しているか、ポインタ以外でオブジェクトを格納している場合。

于 2011-04-19T08:02:32.900 に答える