Безопасно ли удалить указатель NULL?

Можно ли удалить указатель NULL?

И это хороший стиль кодирования?

Ответ 1

delete выполняет проверку в любом случае, поэтому проверка на вашей стороне добавляет лишние накладные расходы и выглядит уродливее. Хорошая практика очень устанавливает указатель на NULL после delete (помогает избежать двойного удаления и других подобных проблем с повреждением памяти).

Мне также понравилось бы, если бы delete по умолчанию устанавливал параметр NULL, как в

#define my_delete(x) {delete x; x = NULL;}

(Я знаю о значениях R и L, но было бы неплохо?)

Ответ 2

Из проекта стандарта С++ 0x.

$5.3.5/2 - "[...] В любом случае альтернатива, значение операнда удаления может быть нулевым указателем значение. [..."

Конечно, никто не будет "удалять" указателя со значением NULL, но это безопасно. В идеале не должно быть кода, который бы удалял указатель NULL. Но иногда полезно, когда удаление указателей (например, в контейнере) происходит в цикле. Так как удаление значения указателя NULL безопасно, можно действительно написать логику удаления без явных проверок для удаления операнда NULL.

В качестве отступления, стандарт C $7.20.3.2 также говорит, что "свободный" по указателю NULL не выполняет никаких действий.

Свободная функция вызывает пробел на который указывает ptr, который должен быть освобожден, то есть доступный для дальнейшего распределение. Если ptr - нулевой указатель, никаких действий не происходит.

Ответ 3

Да, это безопасно.

Нет вреда при удалении нулевого указателя; он часто уменьшает количество тестов в хвосте функции, если нераспределенные указатели инициализируются до нуля, а затем просто удаляются.


Поскольку предыдущее предложение вызвало путаницу, пример - который не является безопасным исключением - того, что описывается:

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 в конце функции не нужно проверять, не являются ли они ненужными в исходном коде; код библиотеки выполняет проверку в любом случае.

Ответ 4

Удаление нулевого указателя не имеет эффекта. Это не очень хороший стиль кодирования, потому что он не нужен, но это тоже неплохо.

Если вы ищете хорошие методы кодирования, подумайте об использовании интеллектуальных указателей, а затем вам не нужно delete вообще.

Ответ 5

Чтобы дополнить ruslik ответ, в С++ 14 вы можете использовать эту конструкцию:

delete std::exchange(heapObject, nullptr);

Ответ 6

Это безопасно, если вы не перегрузили оператора удаления. если вы перегрузили оператор delete и не обрабатывали нулевое состояние, это небезопасно.

Ответ 7

Я испытал, что небезопасно (VS2010) удалять [] NULL (т.е. синтаксис массива). Я не уверен, соответствует ли это стандарту С++.

Безопасно удалять NULL (скалярный синтаксис).