3

C++ 標準によると、割り当てが失敗した場合operator newthrow std::bad_alloc();

この動作をテストするために、次のコードを思い付きました。

try
{
    for (;;)
    {
        Big* p = new Big;
        if (0 == p)
        {
            printf("nullptr");
            break;
        }
    }
}
catch (std::bad_alloc&)
{
    printf("exception");
}

問題は、予期せず、nullptrこれを Windows Mobile 2003 (Windows CE 4.2) で実行するたびに発生することです。

コンパイラは Microsoft (R) C/C++ Optimizing Compiler Version 14.00.60131 for ARM ですので、コンパイラが The Standard に準拠していないということはないと思います。

throw std::bad_alloc()また、指定されたブロック内で手動で試行しましたtry(成功したため、catch失敗した場合にパーツがトリガーされるはずですnew)。別のことはすることでしたset_new_handler()が、それもうまくいきませんでした。念のために言うと、私Bigのサイズは 10MB です。

では、何が欠けているのか教えていただけますか?なぜ私は取得しないのstd::bad_allocですか?

編集1:これを克服する方法を探しているのではなく、そもそもそれが起こる理由を探しています。

編集 2:デバッグへの旅で、プログラムをできる限り単純化しました。new得られた逆アセンブリ出力は次のとおりです。

        int* p = new int[10];
00011010  mov         r0, #0x28 
00011014  bl          00011040       <---- here is the call to operator new
00011018  str         r0, [sp, #0xC] 
0001101C  ldr         r3, [sp, #0xC] 
00011020  str         r3, [sp, #4] 
00011024  ldr         r3, [sp, #4] 
00011028  str         r3, p 

        operator new:
00011040  ldr         r12, [pc]           <---- 
00011044  ldr         pc, [r12]           <----  what are those?
00011048  andeq       r3, r1, r0          <----  is it just that?
0001104C  andeq       r1, r1, r4, lsr #11 <----  nothing else to be seen...     
00011050  streqd      r2, [r1], -r0       <----   

システムコールはありませんか?もっと複雑にすべきではありませんか?誰でもこれを調査するのを手伝ってもらえますか?

4

1 に答える 1

3

これは、MSVC6.0 の動作によく似ているように聞こえますが、プラットフォームの古さを考えれば驚くことではありません。詳細については、こちらをご覧ください。

MSDN マガジン 2003 年 9 月 (bad_alloc の場合は ctrl-f)

Big の new 演算子はいつでもオーバーライドできますが、あまり良い実装ではないことを受け入れて、より良いプラットフォームにコードを移植する場合に備えて std::bad_alloc を引き続き試してキャッチすることをお勧めします。

私は通常、マクロを提唱しませんが、null かどうかをチェックして bad_alloc をスローするマクロを作成することはできます。これは、コードを移植するとすぐに削除できます。(インライン関数も同様に機能する可能性がありますが、実際には、醜い問題に対する醜い修正が必要になる場合があります)。

template<PointerType>
inline void good_alloc(PointerTpye ptr) //throws std::bad_alloc
{
 #if BAD_COMPILER //MSVC version number?
     if(ptr==null)
     {
         throw std::bad_alloc; 
     }
 #else
     //do nothing
 #endif
}
于 2011-12-05T17:03:39.627 に答える