Безопасно ли удалять нулевой указатель? - PullRequest
273 голосов
/ 16 ноября 2010

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

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

Ответы [ 7 ]

239 голосов
/ 16 ноября 2010

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

Я бы тоже хотел, если бы delete по умолчаниюустанавливал для параметра значение NULL, как в

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

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

73 голосов
/ 16 ноября 2010

Из чернового стандарта C ++ 0x.

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

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

Кроме того, в стандарте C $ 7.20.3.2 также говорится, что «free» для NULLуказатель не выполняет никаких действий.

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

43 голосов
/ 16 ноября 2010

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

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


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

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

20 голосов
/ 16 ноября 2010

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

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

5 голосов
/ 08 ноября 2017

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

delete std::exchange(heapObject, nullptr);
3 голосов
/ 16 ноября 2014

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

0 голосов
/ 30 августа 2013

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

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

...