2011-10-05 18 views
8

私はどこのデータブロックにアクセスするためのポインタを使用するコードを持っています。まれに、データブロックのいくつかのメンバーが空であり、結果としてポインタがぶら下がってしまいます。実際、私は正しいポインタを取得しますが、ポインタで何かをしようとするとプログラムがクラッシュします。ポインタがぶら下がっているかどうかを確認する方法はありますか?

通常のアドバイスは、このタイプの使用を避けることです。しかし残念なことに、私が使用するフレームワークでは、このタイプのデータアクセスメソッドを使用する必要があります。

ポインタはそれで何らかの操作を行う前に無効な場合、私は「チェック」することができます方法はありますか?ポインタがNULLに等しくないことを確認することは、明らかに機能しませんでした。私もこれを試した:

try 
{ 
    CString csClassName = typeid(*pMyPointer).name(); // Check error condition 
    // The line below fails due to dangling pointer (data block is not valid). 
    hr = pMyPointer->MyPointerMethod(); 
} 
catch(bad_typeid) 
{ 
    return E_FAIL; 
} 
catch(...) 
{ 
    return E_FAIL; 
} 

それは正しい方法ですか?

答えて

5

ローポインタが有効かどうかをチェックする方法はありません。無効なポインタは、そのポインタにアクセスすると必ず失敗することはありません。生のポインタを使用する代わりに、スマートポインタのいくつかの形式を使用する必要があります。

+0

私のポインタはクラスに静的でなければなりません。それでも問題はありません。私はスマートポインタを使用していますか? – Nikhil

+0

これはまったく問題ありません。あなたはスレッドの安全性の問題に気を付ける必要がありますが、それはスマートポインタと未処理ポインタの違いはありません。 –

+2

私はそれが重要だとは思わない。私の気になる唯一のことは、あなたのフレームワークが、事前の通知なしにあなたのポインタをぶら下げるかどうかということです。あなたがスマートポインタから生のポインタを抽出してフレームワークに渡す必要があります。呼び出し後にポインタが有効なままであることが保証されている場合や、無効になった場合に通知されることが保証されていれば、それを行ってください。 – Septagram

7

あなたは間違った方向を見ていると思います。おそらく、ポインタを正しく初期化していないバグがあります。オブジェクトをあまりにも早く削除し、ポインタが削除された後、または同様のものを再利用しようとしています。そのような場合は、バグを隠す方法を見つけようとするのではなく、なぜそれが起こっているのかを特定し、バグを修正することに集中すべきです。

あなたはtypeid演算子を使用しているアプローチのとおり、答えはそれが有効ではないということです。仮想関数を含まない型のオブジェクトの場合、typeid演算子は、ポインタの静的型に基づいてコンパイル時に解決されます。少なくとも1つの仮想関数を含むオブジェクトの場合は、実行時に解決されますが、無効なポインターを使用してtypeid(p)を呼び出すことは未定義の動作で、動作しているのと同じようにクラッシュする可能性があります。

示唆されているスマートポインタの使用、ライブラリが実際に何をするかで、あなたはすべての回でのスマートポインタの周りに渡すことができるかどうか依存する場合があります。一般的に、あなたがもはやdeleteを手動で、チャンスがあるので、(問題は、初期化がある場合は修正していない)とメモリ管理のためのスマートポインタを使用することをお勧めし、ポインタが正しく初期化されることをターン保証でその意志であるという問題があればもはや起こらない、早期の削除を伴うものである。しかし、これは問題を解決するかもしれないが、私はまだあなたはそれがより大きな問題の症状かもしれないとして、ポインタが、あなたのアプリケーションで無効である理由を理解する必要があると考えていることに注意してください。

ここで、ポインタがぶら下がっているかどうかをチェックする方法については、プログラムではできませんが、メモリデバッガ(linux、Purifyなどのvalgrind)このツールは、ポインタが決して初期化されなかったのか、誤った使用の前にシステムにメモリを解放したのかを判断するのに役立ちます。

+0

あなたの詳細な説明をありがとう。私は、バグを隠す代わりに解決策を見つけるべきであることを理解することができます...しかし、私は短時間で変更できないフレームワークの抜け穴があります。私もスマートポインタで試したが、うまくいかなかった。 – Nikhil

1

スマートポインタは必要ありません。これらは、この問題に対処するための1つの可能なアプローチです。戻ってそれ(referencers)を参照、これらのオブジェクトへの参照オブジェクト内(referencee)、参照のリスト:

あなたは相互の参照を使用することができます。それは、referencersのそのリストを最初の実行referenceeの割当てを解除する時であると割り当て解除、その後、(通常は、これは可能と思われるプロパティ事前に知ってほしいと思います)nullに、彼らはreferenceeを指すように使用する任意のプロパティを設定すると、参照。

関連する問題