2012-01-25 5 views
4

Что является лучшим способом проверки возврата указателя на new operator Я вижу следующий тип кода. Предположим, у меня есть class Testуказатель return by new check in C++

Тип 1

Test *ptr = new Test; 
if (ptr == NULL) { 
} 

Тип 2

Test *ptr = new Test; 
if (!ptr) { 
} 

Тип 3

Test *ptr = new Test; 
if (ptr == (Test*)0) { 
} 
+2

Пожалуйста, определить, что вы подразумеваете под «лучше». А как насчет исключений? Используете ли вы специальный 'новый', который не вызывает исключений? –

+1

лучшим будет 'if (ptr == nullptr)', но это предполагает совместимый с C++ 11 компилятор. – PeterT

+0

Вы случайно посмотрите на старый код Win32/Windows/COM? Текущий код на C++ генерирует исключения в случае новых сбоев; но прежде чем исключения были широко поддержаны, вам нужно было проверить NULL.Иногда Windows или COM-код отказывается от использования исключений, чтобы избежать портирования старых кодовых баз или просто потому, что с ними иногда легче справляться: COM требует, чтобы все исключения были преобразованы в HRESULT перед возвратом из интерфейса. См. Ответ на [этот вопрос SO] (http://stackoverflow.com/a/550457/660175) для получения более подробной информации. – BrendanMcK

ответ

9

Вы не проверяете new для нулевой он бросает исключение std::bad_alloc в случае выходит из строя.
Итак, вы обрабатываете исключение.

Конечно, указанное правило применяется, если вы не используете nothrow версию new.

try 
    { 
    Test *ptr = new Test; 
    } 
    catch (std::bad_alloc &e) 
    { 
    cout << "new Failed"; 
    } 
+0

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

+1

На самом деле это правильный ответ на вопрос, потому что не будет никакого случая, когда Test * ptr = new Test; будет иметь значение NULL или 0. –

+0

@DavidHeffernan: Проверка возвращаемого значения указателя, возвращаемого 'new', бесполезна. Вам нужно обработать исключение, которое об этом. Если вы собираетесь предложить OP проверить возвращаемое значение' new', то поздравления вы просто потеряли из самого важного края 'new' предоставляет более' malloc'. Ввиду того, что я не вижу, как он не отвечает на вопрос. –

1

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

С другой стороны VC6 сделать возвращение-на bad_alloc в этом случае типа 3 должна быть прекрасно в тех случаях, когда у вас нет nullptr (что в стандарте C++ 11)

Другим способом быть в состоянии проверить на NULL, чтобы назвать новыми с стандом :: nothrow:

ptr = new(std::nothrow) Test(); 

в любом случае помните, что вы не должны поймать каждый bad_alloc где брошен. Вам лучше поймать его, где вы можете ответить на него (свободная память или умереть грациозно).

0

Предполагая, что ваш Распределитель/реализация возвращает 0 вместо того, чтобы выбросить, я думаю, что это самое лучшее:

Test* const ptr(new Test); 
if (0 == ptr) { 
// uh-oh 
} 

0 распространена в C++, и вы не будете делать ошибку, назначая указатель с константой налево.

Если это местное к if, вы можете, как это:

if (Test* const ptr = new Test) { 
// use it 
} 
0

Всегда старайтесь LHS быть постоянным для оператора ==

Test *ptr = new Test; 
if (NULL == ptr) { } 

Здесь, по ошибке, если вы пишете = вместо of ==, это даст ошибку компиляции.

Но если вы пишете, если (PTR = NULL), он не будет давать какие-либо ошибки, NULL будет назначен PTR

+1

Мой компилятор предупредит меня в любом случае. Нет необходимости запутывать код. –