Linux C++ アプリケーションがあり、逆参照する前にオブジェクト ポインターの有効性をテストしたいと考えています。ただし、Linux ではセグメンテーション違反のため、try/catch は機能しません。これはどのように行うことができますか?
9 に答える
アプリ全体の多くのポインターが同じ期間限定オブジェクトを参照するシナリオがある場合、一般的な解決策はブースト スマート ポインターを使用することです。 編集: C++11 では、これらの型の両方が標準ライブラリで利用可能です
shared_ptr
オブジェクトの有効期間を担当するweak_ptr
ポインターと、無効になる可能性のある他のポインターに使用する必要があります。weak_ptr
求めている有効性チェックが組み込まれていることがわかります。
セグメンテーション違反は例外ではありません (Java の NullPointerException など)。これは、OS からプロセスに送信されるシグナルです。セグメンテーション違反 (SIGSEGV) のハンドラーをインストールする方法については、sigaction のマンページを参照してください。
この 1 回のオカレンスに対して、SIGSEGV のシグナル ハンドラーを有効にすることができます。詳細については、man ページの「signal」を参照してください。もう 1 つの方法は、有効であることが保証されている参照を使用することです。もちろん、アプリケーションによって異なります。
ポインターを NULL に初期化します。何らかの処理を行ってもまだ NULL である場合は無効であり、そうでない場合は有効です。
生のC++ポインターを使用する自然で普遍的な方法はありません。C ++は、その情報を追跡することを前提としています。
ほとんどの場合、ポインタが無効な場合はポインタをNULLに設定することを忘れないで、これを処理できます。最初にポイントしない新しいポインタはNULLに設定する必要があり、新しく削除されたオブジェクトのポインタはNULLに設定する必要があります。
ポインターの有効性をどのようにテストしますか? NULL と比較しますか?
最善の方法は、プログラムをValgrindの下で実行することです。バグはまったく別の場所にある可能性があります。
更新: Win32 プラットフォームでは、いくつかの例外をキャッチできる __try __except のようなものがあります。私の知る限り、その Win32 機能に相当する Linux はありません。
一般に、「NULL以外のポインターの有効性をチェックする」という非常に奇妙なアイデアについては、次の記事を参照してください。http: //blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx( 「IsBadXxxPtrは実際にはCrashProgramRandomlyと呼ばれるべきです」)
ポインタはオブジェクトに格納されます。それらはコンストラクターで初期化され、場合によっては 0 (NULL) に初期化されます。それらはデストラクタで削除され、おそらく代入で削除され、他の関数ではめったに削除されません。デストラクタ以外のメンバーで削除されると、すぐに新しい値または 0 が割り当てられます。
ハンドラーを SIGSEGV にアタッチすると、エラーが発生したという事実をログに記録して正常に失敗する以外にできることはあまりありません。この違反が発生すると、プログラムは未定義の状態になるため、通常の操作を安全に続行できない可能性があります。
NULL をチェックする以外に、あなたが説明している意味でポインターが「有効」であるかどうかをチェックする方法があるとは思いません。通常の操作では、このようなエラーはバグであるため発生すべきではありません。