2011-01-26 3 views
4

Возможный дубликат:
Test for void pointer in C++ before deletingC++: Проверка NULL при удалении

Является ли фрагмент кода 1 эквивалент фрагмент 2?

//Snippet 1: 
    delete record;   
    record = new Record; 


//Snippet 2  
    if (record != NULL) 
    { 
     delete record; 
     record = NULL; 
    }  
    record = new Record; 
+1

дубликатов (только первая страница результатов, их еще много): http: // stackoverflow.com/questions/615355/is-there-any-reason-to-check-for-a-null-pointer-before-delete http://stackoverflow.com/questions/4190703/is-it-safe-to-delete -a-null-pointer http://stackoverflow.com/questions/3821261/null-check-before-deleting-an-object http://stackoverflow.com/questions/724688/how-many-of-you-are -aware-that-its-safe-to-delete-a-null-pointer http://stackoverflow.com/questions/1558013/delete-null-but-no-compile-error http://stackoverflow.com/questions/3844374/test-for-void-pointer-in-c-before-deleting –

ответ

8

Единственное отличие, которое я вижу, состоит в том, что если конструктор Record создает исключение, первый образец может оставить значение переменной record устаревшим, а во втором - NULL.

EDIT:
Действительно, первый образец, если он повторен позже, приведет к двойному удалению.

delete record; 
record = new Record; // Throwing exception 
// record points to old object 
// ... later ... 
delete record; // Double deletion - sky falls down etc. 

Безопасная форма будет:

delete record; record = 0; 
record = new Record; // Can throw an exception if it likes 

Или использовать std::auto_ptr вместо исходного указателя.

+0

... что может привести к проблеме двойного удаления, как отметил Джеймс (просто добавив для полноты). – etarion

3

Они одинаковы в том, что у вас есть новый рекорд в конце каждого из них, но фрагмент кода два имеет ненужную проверку на NULL перед удалением.

1

Оператор delete в C++ должен работать правильно (ничего не делать), когда указатель имеет значение NULL, поэтому оба фрагмента кода одинаковы. См. Например, http://opensource.devx.com/tips/Tip/14443.

1

Да, это: delete на указателе NULL, как ожидается, будет работать как в последнем коде.

Смотреть $ 5.3.5:

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

1

Ответ на вопрос: результат такой же записи IF - это указатель на запись (с оговорками, описанными в других сообщениях, по поводу метаданных конструктора). Если это тип класса с неявным преобразованием в указатель, результат может быть не таким (потому что операторы могут быть перегружены.)

6

Это зависит от объема записи. Если это член класса и удаляется в деструкторе, то нет, они не совпадают. Первая версия может оставить вас с проблемой двойного удаления (если новая запись() выбрасывает), потому что запись не является NULL.

Если у него есть область функционального уровня, я думаю, что вторая версия является излишней.

Вторая версия более безопасна.

+0

хорошо catch. Возможно, вы захотите упомянуть, что это происходит в случае, когда генерирует конструктор Record, и он должен назначить 0 указателю, а не проверке на null перед удалением. – etarion

+0

done ........... – James

+0

+1 для определения того, что просил допрашивающий и всех проголосовавших: название не отражает тело вопроса. –

Смежные вопросы