Windows Mobile возвращает 0 в случае «новой» ошибки - PullRequest
0 голосов
/ 05 мая 2011

У меня есть проект Visual Studio 2008 для Windows Mobile 6.5.3 ARMV4I.Я проверяю нехватку памяти с помощью блока try / catch, ища исключения std::bad_alloc.Но в ходе тестирования я обнаружил, что он может просто возвращать значение NULL и не генерировать исключение.

int _tmain( int argc, _TCHAR* argv[] )
{
    int i = 0;

    try
    {
        for( ; i < 30000; ++i )
        {
            BYTE* f = new BYTE[1024];
            if( NULL == f )
            {
                NKDbgPrintfW( L"NULL - Survived %d iterations\r\n", i );
                break;
            }
        }
    }
    catch( std::bad_alloc& )
    {
        NKDbgPrintfW( L"std::bad_alloc - Survived %d iterations\r\n", i );
    }

    return 0;
}

Это печатает: NULL - Survived 29599 iterations.

Я не связываюсь с nothrownew.obj и в соответствии с этим я должен ожидать исключение std::bad_alloc.http://msdn.microsoft.com/en-us/library/kftdy56f%28v=VS.90%29.aspx

Кто-нибудь знает, что происходит?

Спасибо, PaulH

Ответы [ 2 ]

2 голосов
/ 05 мая 2011

То, что вы наблюдаете, просто означает, что библиотека, поставляемая с компилятором, не работает.Он нарушен в том смысле, что он не соответствует требованиям стандарта языка C ++.

Эта конкретная проблема с new присутствовала в более ранних версиях стандартной библиотеки C ++ (например, той, что поставлялась с VC 6.0).Позже некоторые версии компилятора / библиотеки были обновлены для соответствия стандартным требованиям.По-видимому, версия для Windows Mobile осталась без изменений.

Вполне возможно, что это было сделано намеренно, чтобы сохранить совместимость со старым кодом.Вы могли бы также хотеть проверить некоторый переключатель конфигурации компилятора, который мог бы управлять этим поведением.Я не знаю, существует ли такой переключатель.

0 голосов
/ 05 мая 2011

Стиль ошибки зависит от типа используемого нового выражения. Стандарт говорит об этой функции распределения:

5.3.4 / 13:

[Примечание: если только функция распределения объявляется с пустым спецификация исключения (15.4), throw (), это указывает на сбой выделить хранилище, бросая исключение bad_alloc (пункт 15, 18.4.2.1); в противном случае он возвращает ненулевой указатель. Если распределение функция объявлена ​​с пустым спецификация исключения, throw (), это возвращает ноль, чтобы указать сбой выделить память и ненулевой указатель иначе. ]

Затем в 18.4.1.1/5 мы узнаем, что версия функции выделения nothrow вызывается только в стиле размещения new выражение, указывающее nothrow:

Эффекты: То же, что и выше, за исключением того, что вызывается версией размещения новое выражение, когда программа на C ++ предпочитает нулевой результат указателя как индикация ошибки, вместо исключение bad_alloc.

Другими словами, компилятор выглядит не соответствующим. Скорее всего, это позволит избежать библиотечного кода, необходимого для поддержки исключений на мобильных устройствах, и, вероятно, задокументирован как часть документации компилятора Windows Mobile.

...