2016-05-30 11 views
2

私はこのようなヌルポインタをチェックする私のチームの人たちをたくさん見てきました:gcc(4.9)でstd :: nothrowが期待どおりに動作しないのはなぜですか?

SomeClass *pSc = new SomeClass; 
    if (NULL == pSc) 
    { 
     // cope with error 
    } 

私が知られている、これは動作しません、C++のnew演算子の代わりにNULLを返すのstd :: bad_alloc例外がスローされますので。私はstd :: nothrowが本当に起こることを期待できるものを作ることができることも知っています。

#include <iostream> 
    #include <limits> 
    #include <new> 
    using namespace std; 

    void myNewHandler() 
    { 
     std::cerr << "Failed to allocate memory!" << std::endl; 
    } 

    int main(int argc, char* argv[]) 
    { 
     //std::new_handler oldHandler = std::set_new_handler(myNewHandler); 

     int *pLotsMem = new(std::nothrow) int[std::numeric_limits<long long>::max()]; 
     if (nullptr == pLotsMem) 
     { 
      std::cerr << "Allocation failed" << std::endl; 
      return -1; 
     } 
     else 
     { 
      delete[] pLotsMem; 
      pLotsMem = nullptr; 
     } 

     //std::set_new_handler(oldHandler); 

     return 0; 
    } 

はい、私は同様のstd :: set_new_handlerの使用を実証したかった:だから私はこのような例を書きました。私の驚いたことに、これでもうまくいきませんでした。新しい演算子はまだ例外をスローしました(std :: bad_array_new_length、std :: bad_allocの派生クラス)、プログラムを終了しました。

なぜこれがうまくいかないのですか? gccのnew演算子によって返されたポインタをチェックするにはどうすればよいですか?

+0

期待通りに動作します –

+0

はい!また、vC++コンパイラでも動作します。しかし、なぜgccでうまくいかないのか分かりません。 –

+1

'GCC 6.1.0'では、サイズを正当な量に減らさない限りコンパイルされません。それは期待どおりに動作します。 – Galik

答えて

4

、これは標準準拠の動作である信じられないかもしれません:

5.3.4/7

noptr-新宣言子内の式が誤っている場合:
[...] - その値は、割り当てられたオブジェクトのサイズが実装定義の制限(附属書B)を超えるような値です。または
[...]

発現は、はstdする:: size_t型を変換した後、コア定数 発現および発現が誤っている場合、プログラムが悪い形成されています。それ以外の場合は 、誤った表現でnew式は、(18.6.2.2)がない コール配分機能を行い、 のタイプ STDのハンドラ(15.3):: bad_array_new_lengthにマッチするタイプの例外をスローすることで終了します。 式の値がゼロの場合、割り当て関数が呼び出され、要素のない配列 が割り当てられます。さえ呼ばれていない短い、非投げアロケータ関数で

は、例外がnew式自体によってスローされます。

私はそれらのstd::numeric_limits<long long>::max()constexprとしてマークされ、コンパイル時にエラーが生成さコア定数式、であるので、あなたは、現代のC++バージョンを使用していないことを前提としています。

クラン、おそらく実装定義の限界を持っては、C++のこの癖をバイパスして、長いロンドの最大値よりも高く設定しました。

+0

ありがとう! nullptrをNULLに戻し、 "-std = C++ 11"オプションを付けずにコードをコンパイルしました。今回は期待通りに機能しました。最も現代的なC++は非常に異なっています。私にとって学ぶべきことがたくさんあります。 –

+2

http://wg21.link/cwg1992 –

関連する問題