2017-01-18 1 views
0

私はアプリケーションでセグメント違反やその他の未知の例外を捕捉する必要があります。しかし、私はそれをどうやってできるのか分かりません! この目的でstd :: uncaught_exceptionsを使用できますか?std :: uncaught_exceptionsはすべての例外を回避するのに便利ですか?

+0

できません。 SegfaultはC++の下で生成されます。これは例外でもなく、C++のものでもありません。 – user4581301

+0

あなたは読むことができます:http://stackoverflow.com/questions/457577/catching-access-violation-exceptions –

+6

あなたはそれをキャッチし、*何*正確にする必要がありますか?これは本当にあなたが安全に回復できるものではありません。 SEGVは、あなたのコードが何とか真剣に壊れていることを意味します。おそらく根本原因を修正するために努力する必要があります。 – paxdiablo

答えて

1

この目的にはstd::uncaught_exceptionsを使用できますか?

int main(int argc, char* argv[]) 
{ 
    int *val = NULL; 
    *val = 1; 
    std::cout << "uncaught: " << std::uncaught_exceptions() << std::endl; 
    return 0; 
} 

これは、おそらくセグメンテーションフォールトが発生しますし、何も出力されません。

は、このコードを考えてみましょう。

私のアプリケーションでは、セグメント化エラーやその他の未知の例外を捕捉する必要があります。しかし、私はそれをどうやってできるのか分かりません! C++での

例外処理はtry-catchブロックを介して行うことができます、そしてあなたはたとえば、SIGSEGV, SIGFPE, or SIGILLのような特定のエラーをキャッチするためにstd::signal機能を使用することができます。

#include <iostream> 
#include <exception> 
#include <csignal> 
#include <cstdio> 

extern "C" { 
    void sig_fn(int sig) 
    { 
     printf("signal: %d\n", sig); 
     std::exit(-1); 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    int *val = NULL; 
    std::signal(SIGSEGV, sig_fn); 
    try { 
     *val = 1; 
    } catch (...) { 
     std::cout << "..." << std::endl; 
    } 
    if (std::uncaught_exception()) { 
     std::cout << "uncaught" << std::endl; 
    } 
    std::cout << "return" << std::endl; 
    return 0; 
} 

しかし、あなたは注意する必要があり、その例外のこのタイプ処理は本当にクリーンアップとシャットダウンを行うことを意味し、必ずしもキャッチアンドリリースする必要はありません。たとえば、次のコードを入力してください:

#include <iostream> 
#include <exception> 
#include <csignal> 
#include <cstdio> 

extern "C" { 
    void sig_fn(int sig) 
    { 
     printf("signal: %d\n", sig); 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    int *val = NULL; 
    std::signal(SIGSEGV, sig_fn); 
    while (true) { 
     try { 
      *val = 1; 
     } catch (...) { 
      std::cout << "..." << std::endl; 
     } 
    } 
    if (std::uncaught_exception()) { 
     std::cout << "uncaught" << std::endl; 
    } 
    std::cout << "return" << std::endl; 
    return 0; 
} 

このコードは、セグメンテーションフォルトを永遠に引き起こします。

セグメンテーションフォルトを捕まえようとしている場合は、セグメンテーションフォルト(またはそれに関するエラー)が最初に発生した理由を調査し、その問題を修正する必要があります。一例として、上記のコードを使用してさらなる読書のために

int *val = NULL; 
if (val == NULL) { 
    std::cout << "Handle the null!" << std::endl; 
} else { 
    *val = 1; 
} 

を:here is a SO Q&Aセグメンテーション違反は、同様に、その上にhere is the Wikiあり、そしてMITがあまりにも取り扱いとデバッグセグメンテーション違反についていくつかのヒントを持っているものに。

希望に応じることができます。

+0

最初の例は、C++標準による未定義の動作です。おそらくプログラマとしてのあなたの介護者で遭遇するすべてのシステムにセグメンテーションが発生しますが、保証はありません。 – user4581301

+0

@ user4581301 ..技術的には、すべての例がヌルポインタを逆参照しているので、すべての例はUBです。 OPの例外とシグナルに関する知識を与えられたので、私はOPがそれを(UBの代わりに)エラーと見なすべきであることを表現しようとしていました。私は_always_を_likely_に変更しました。このコードは 'int * v = NULL; try {* v = 1; } catch(...){std :: cout << "" ... "<< std :: endl; } 'は期待通りに動作しますが、他のプラットフォームでは動作しません(技術的にはコードではsegfaultが発生するはずですが、Windows内部のsegfault割り込みハンドラは実際に捕捉されたエラーを'スローします)。 – txtechhelp

関連する問題