2017-01-19 13 views
1

При использовании нового и исключается исключение bad_alloc. Вам все еще нужно позвонить delete на ptr, прежде чем продолжить, или вы можете быть уверены, что память не выделена?По ошибке плохого размещения нового, удалить все еще нужно назвать?

Как насчет того, если вы используете версию nothrow? можете ли вы снова быть уверены, что память не была выделена, если возвращается nullptr?

+0

С какими "ptr" вы говорите? Поместите некоторый код. –

+0

любой ptr, который выделяется памятью через новый –

+0

Сообщение. Некоторые. Код. Первая часть вопроса неосуществима как написана, а пограничная бессмысленная. Когда 'new' бросает, оценка выражения не завершается. –

ответ

2

Когда исключение, вы не «вести» - выполнение переходит к обработчику улова.

В выражении типа:

p = new int; 

суб-выражения new int сначала вычисляется. Если это генерирует исключение, выполнение не достигает назначения. p сохраняет прежнее значение (если оно есть).

В случае p = new(std::nothrow) int;, то при отсутствии распределения p станет нулевым указателем. Он не имеет никакого эффекта для вызова delete по нулевому указателю.

+0

Нет, его нет. Вы ответили на это. Я спрашивал, можете ли вы быть уверены, что никакого присвоения не было и/или памяти не было выделено. –

2

версия nothrow из new действительно сообщают об ошибках, возвращая нулевой указатель, в этом случае не было выделено никакой памяти и ни один объект не был построен:

T * p = new (std::nothrow) T(a, b, c); 

if (p) 
{ 
    // stuff 
} 

delete p; // OK, works on null pointers, too. 

Или, может быть:

if (T * p = new (std::nothrow) T(a, b, c)) 
{ 
    // stuff 
    delete p; 
} 
else 
{ 
    // allocation failure 
} 

Или еще лучше:

if (std::unique_ptr<T> p(new (std::nothrow) T(a, b, c))) 
{ 
    // stuff 
} 

Последняя версия автоматически удаляет динамический объект при любом выходе из блока if, что является типичным примером обработки C++ нескольких выходов и, таким образом, локализации сложности.

(Может быть, должно быть шаблон make_unique_or_null функции инкапсулировать этот последний бит.)

+1

Конечно, во втором примере проблема утечки памяти, если '// stuff' может выкинуть –

+0

@ M.M: Первый пример также имеет эту проблему. Я предполагаю, что вы, как правило, знаете о необходимости правильного кода с исправлением ошибок. –

+1

Да, я думаю, было бы хорошо, если бы ваш ответ упоминал об этом на каком-то этапе, если не понятно начинающему, что преимущество последней версии –