他の誰かのコードをデバッグするとき、ポインターが削除されたときをどのように見つけることができますか?
6 に答える
1)
デバッガーを使用します。1 つの削除に従います。一般に、ポインターを渡す「フリー」関数になります
過去のポインターが調査したポインターと同じ値を持つという条件でブレークポイントを設定します
2)
同様のアプローチの 1 つは、「delete」メソッドをオーバーライドして、問題のポインターをチェックすることです。
3)
ポインタがデストラクタを持つオブジェクトを参照している場合。デストラクタにブレークポイントを配置します。最初にデストラクタを追加することをお勧めします (可能な場合は外部コードで、常に独自のコードで可能です)。
問題の型のデストラクタに条件付きブレークポイントを設定します。this
関心のあるオブジェクトを指す条件とします。たとえば、Visual C++ Express 2010 の場合:
上の図では、最初に 3 つのnew
式の後に実行し、次にb
オブジェクトのアドレスを記録し、そのアドレスであるthis
必要があるブレークポイント条件として使用しました。
他のデバッガーでこれを行う方法の詳細は、デバッガーによって異なります。デバッガのマニュアルを参照してください。
C++ には、ポインターが削除されているかどうかを検出するクロスプラットフォーム機能が組み込まれていません。
ただし、一部のデバッガー、ツール、および言語自体が提供する機能を使用できます。たとえば、new
anddelete
演算子をグローバルにオーバーロードしたり、クラスベースごとにオーバーロードしたり、共通のセット/マップの種類の参照を維持したりできます。例えば:
class X {
...
set<void*> m_CurrentAlloc;
public:
void* operator new (size_t SIZE)
{
...
m_CurrentAlloc.insert(p);
return p;
}
void operator delete (void *p)
{
m_CurrentAlloc.erase(p);
...
}
};
定期的に、またはプログラムの最後に、この内容をset
印刷または確認できます。
これは、 を使用してメモリ管理を行っている理想的な状況のソリューションであることを忘れないでくださいnew/delete
。malloc/free
あまりにも混在している場合、コードには他の拡張機能も必要です。
GDBウォッチポイントはどうですか?問題のポインターにウォッチポイントを設定し、プログラムが参照先を削除するためにいつアクセスするかを確認できます。
ポインタが指すメモリを参照している場合は、できません。ただし、ダングリングポインターに問題がある場合は、生のポインターをすべて boost::shared_ptr に置き換えて、free と delete をすべて削除します。delete または free キーワードは使用しないでください。スマート ポインタが揺れる!
できません。スマート ポインターを使用し、心配する必要はありません。