1

私がやろうとしている:C++ Builderでアクセス違反例外を処理しますか?

try{ 
    int * i = NULL; 
    *i = 3; 
}catch(Exception &Err){ 
    ShowMessage(Err.Message); 
} 

私はしかし、これはアクセス違反の例外をキャッチし、エラーメッセージを表示することによって、それを処理する必要があること。

しかし、私が代わりにフル1

の簡単な

アクセス違反

メッセージモジュールYYYでアクセス違反XXX得る何らかの理由で。アドレスZZZに書き込む。

BTW、ExceptObject()ルーチンは何らかの奇妙な理由でNULLを返します。

私はここで何が欠けていますか?

+0

これは、動作するはずの方法であるため、「アクセス仮想化」だけが表示されています。 RTLは例外データ全体をスローされるEAccessViolationオブジェクトに格納しません。 ExceptObject()に関しては、あなたが使っているC++ Builderのバージョンを言っていませんでした。 ExceptObject()とExceptAddr()は、古いバージョンのC++ではバグがあることが知られています。 –

答えて

1

Mixing SEH and C++ ExceptionsのMSDNブログのエントリを参照してください。これらは2つの異なるタイプの例外です。 OSで生成された構造化された例外をC++の例外としてキャッチしようとすると、そのままの状態で正しい方法ではありません。 このビットをthis posting on not doing thatで調整します。

アクセス違反をキャッチすることは良い目標になる可能性がありますが、デバッグのコンテキスト内でしか実行したくないもの。プロダクションコードでアクセス違反(またはその他の大きな例外)をキャッチしてそれらを処理しようとすると、正しい操作が行われることはめったにありません。

-1
try { 
    int * i = NULL; 
    *i = 3; 
} 
catch (...) { 
    // This would catch the access violation but you don't have any more 
    // information of what has gone wrong 
} 

ただし、構造化例外処理(SEH)を使用して、すべてのC++例外をキャッチすることはできます。 C++の例外はSEHに基づくクラスベースの実装なので、

+0

いいえ、segフォールトであり、キャッチ(...)さえもキャッチできません。 – Sesh

0

標準C++では、NULLポインタの逆参照によって例外がスローされることは指定されていません。その結果、未定義の動作が発生します。 Windowsプラットフォームでは、WindowsのStructured Exception Handlingによって水が多少混乱します。これはC++の例外処理とは関係がありませんが、一部のC++ランタイムはこれらの例外をC++の例外に変換する可能性があります。しかし、そのような翻訳に依存するコードは移植性がありません。 EAccessViolationを引くBCB5で

1

は、働く例えば:CLASS_NAMEがこのプロジェクトに特有のものであり、おそらくAnsiStringの(this->クラス名)に置き換えられたり除外されるべきであると

#define AV_TRY { try { 

#define AV_CATCH } catch(EAccessViolation &av) {Application->MessageBox((("Access Violation caught: " + string(__FILE__) + "; " + string(__FUNC__) + "; " + IntToString(__LINE__) + "\n\n") + av.Message.c_str()).c_str(), ("Program Error in " + string(class_name.c_str())).c_str(), MB_OK);} } 

注意。また、私はこのコードをサイレントモードでデータベースに、MessageBoxを表示するように切り替えました。私はAV_TRY ... AV_CATCHでAVsを観察したところでコードを折り返します。

関連する問題