Почему я не получаю std :: bad_alloc в своем приложении WinCE? - PullRequest
3 голосов
/ 05 декабря 2011

В соответствии со стандартом C ++, operator new должен throw 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 ++ версии 14.00.60131 для ARM, так что я думаю, что это не тот случай, когда компилятор не соответствует стандарту.

Я такжепопытался вручную throw std::bad_alloc() внутри данного блока try (и это удалось, поэтому часть catch должна сработать в случае сбоя new).Другое дело было set_new_handler(), но это тоже не сработало.В случае, если это важно, мой Big имеет размер 10 МБ.

Так что вы можете сказать мне, что мне не хватает?Почему я не получаю 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       <----   

МусорЕсть ли какие-либо системные вызовы?Разве это не должно быть сложнее?Кто-нибудь может помочь с расследованием этого?

1 Ответ

3 голосов
/ 05 декабря 2011

Это очень похоже на поведение MSVC6.0, что неудивительно, учитывая возраст платформы.Подробнее об этом можно прочитать здесь.

MSDN Magazine сентябрь 2003 (ctrl-f для bad_alloc)

вы всегда можете переопределить новый оператор для Big, но я бы посоветовалпротив этого, просто признайте, что это не очень хорошая реализация, и продолжайте пытаться поймать 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
}
...