Полезно ли проверять возвращение «нового» в C ++? - PullRequest
24 голосов
/ 27 октября 2008

Я обычно никогда не вижу тестов для нового в C ++, и мне было интересно, почему.

Foo *f = new Foo;

// f is assumed as allocated, why usually, nobody test the return of new?

Ответы [ 6 ]

46 голосов
/ 27 октября 2008

Согласно текущему стандарту, new никогда не возвращает NULL , вместо этого он выдает std :: bad_alloc. Если вы не хотите, чтобы new выдавал (в соответствии со старым стандартом), а вместо этого возвращает NULL, вы должны вызвать его, добавив к нему « (std :: nothrow) ». т.е.

Foo* foo = new (std::nothrow) Foo;

Конечно, если у вас очень старый или, возможно, сломанный набор инструментов, он может не соответствовать стандарту.

7 голосов
/ 27 октября 2008

Все зависит от вашего компилятора. VC ++ до версии 6 выдает NULL в случае сбоя нового оператора в приложении без MFC.

Теперь проблема становится больше, когда вы используете, например, STL с VC ++ 6, потому что STL соответствует стандартам, которые он никогда не будет проверять на NULL, когда ему нужно получить немного памяти, и угадывать, что произойдет в условиях нехватки памяти .. ..

Так что для всех, кто все еще использует VC ++ 6 и STL, проверьте эту статью на предмет исправления. Не позволяйте ошибкам выделения памяти разрушить ваше устаревшее приложение STL

4 голосов
/ 27 октября 2008

Все зависит от того, какая версия C ++ предназначена для кода. Спецификация c ++ уже давно заявляет, что, по крайней мере, по умолчанию, сбои в new вызовут исключение c ++, поэтому любой код, выполняющий тест, будет полностью избыточным. В настоящее время большинство программ также нацелено на операционные системы с виртуальной памятью, где почти невозможно исчерпать память, и условие нехватки памяти в любом случае настолько фатально, что просто дать сбой приложения при следующем доступе NULL - это хороший способ любого из терминатор.

Это действительно только во встроенном программировании, где обработка исключений считается слишком большой нагрузкой, а память очень ограничена, и программисты стараются проверять наличие новых ошибок.

3 голосов
/ 27 октября 2008
  1. new выбрасывает std::bad_alloc по умолчанию. Если вы используете значение по умолчанию, проверка на null устарела, но обработка исключений необходима. Такое поведение по умолчанию согласуется с парадигмой безопасности исключений C ++ - обычно она предусматривает, что объект либо создан, либо не выделен

  2. если вы переопределяете значение по умолчанию с помощью new (std::nothrow), проверка на ноль необходима. «Новый» одновременно распределяет и фиксирует страницы, поэтому возможно исчерпание памяти либо потому, что у вас исчерпаны дескрипторы страниц, либо из-за отсутствия физической памяти

  3. исследуйте управление памятью вашей ОС. Эталонный компьютер C / C ++ не знает, как ваша ОС управляет памятью, поэтому полагаться на один язык небезопасно. Пример неправильного распределения памяти читайте в C malloc() + overcommit Linux

3 голосов
/ 27 октября 2008

Как указано здесь

"В компиляторах, соответствующих стандарту ISO C ++, если для выделения недостаточно памяти, код генерирует исключение типа std :: bad_alloc. Весь последующий код прерывается, пока ошибка не будет обработана в try-catch блок или программа аварийно завершает работу. Программе не нужно проверять значение указателя; если исключение не выдано, распределение выполнено успешно. "

0 голосов
/ 27 октября 2008

Обычно никто не проверяет возврат нового в новом коде, потому что Visual Studio теперь бросает то, что говорит стандарт.

В старом коде, если был сделан взлом, чтобы избежать броска, вам все равно лучше протестировать.

...