Можно ли удалить указатель NULL?
И это хороший стиль кодирования?
Можно ли удалить указатель NULL?
И это хороший стиль кодирования?
delete
выполняет проверку в любом случае, поэтому проверка на вашей стороне добавляет лишние накладные расходы и выглядит уродливее. Хорошая практика очень устанавливает указатель на NULL после delete
(помогает избежать двойного удаления и других подобных проблем с повреждением памяти).
Мне также понравилось бы, если бы delete
по умолчанию устанавливал параметр NULL, как в
#define my_delete(x) {delete x; x = NULL;}
(Я знаю о значениях R и L, но было бы неплохо?)
Из проекта стандарта С++ 0x.
$5.3.5/2 - "[...] В любом случае альтернатива, значение операнда удаления может быть нулевым указателем значение. [..."
Конечно, никто не будет "удалять" указателя со значением NULL, но это безопасно. В идеале не должно быть кода, который бы удалял указатель NULL. Но иногда полезно, когда удаление указателей (например, в контейнере) происходит в цикле. Так как удаление значения указателя NULL безопасно, можно действительно написать логику удаления без явных проверок для удаления операнда NULL.
В качестве отступления, стандарт C $7.20.3.2 также говорит, что "свободный" по указателю NULL не выполняет никаких действий.
Свободная функция вызывает пробел на который указывает ptr, который должен быть освобожден, то есть доступный для дальнейшего распределение. Если ptr - нулевой указатель, никаких действий не происходит.
Да, это безопасно.
Нет вреда при удалении нулевого указателя; он часто уменьшает количество тестов в хвосте функции, если нераспределенные указатели инициализируются до нуля, а затем просто удаляются.
Поскольку предыдущее предложение вызвало путаницу, пример - который не является безопасным исключением - того, что описывается:
void somefunc(void)
{
SomeType *pst = 0;
AnotherType *pat = 0;
…
pst = new SomeType;
…
if (…)
{
pat = new AnotherType[10];
…
}
if (…)
{
…code using pat sometimes…
}
delete[] pat;
delete pst;
}
Есть все виды нит, которые можно выбрать с помощью кода примера, но концепция (я надеюсь) понятна. Переменные указателя инициализируются на ноль, так что операциям delete
в конце функции не нужно проверять, не являются ли они ненужными в исходном коде; код библиотеки выполняет проверку в любом случае.
Удаление нулевого указателя не имеет эффекта. Это не очень хороший стиль кодирования, потому что он не нужен, но это тоже неплохо.
Если вы ищете хорошие методы кодирования, подумайте об использовании интеллектуальных указателей, а затем вам не нужно delete
вообще.
Чтобы дополнить ruslik ответ, в С++ 14 вы можете использовать эту конструкцию:
delete std::exchange(heapObject, nullptr);
Это безопасно, если вы не перегрузили оператора удаления. если вы перегрузили оператор delete и не обрабатывали нулевое состояние, это небезопасно.
Я испытал, что небезопасно (VS2010) удалять [] NULL (т.е. синтаксис массива). Я не уверен, соответствует ли это стандарту С++.
Безопасно удалять NULL (скалярный синтаксис).