Что будет, если вызвать delete (или delete[]) на nullptr в C++?

«Что будет, если вызвать delete (или delete[]) на nullptr в C++?» — вопрос из категории Управление памятью, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Это абсолютно безопасная и корректная операция. Согласно стандарту C++ (начиная с C++11), вызов delete или delete[] на нулевом указателе (значении nullptr или унаследованном NULL) не имеет никакого эффекта (является no-op).

Почему это полезно: Это избавляет от необходимости явных проверок перед удалением.

MyClass* ptr = nullptr;
// ... какой-то код, который может или не может выделить память ...
delete ptr; // Всегда безопасно. Если ptr == nullptr, ничего не происходит.

Важные уточнения:

  1. До C++11 поведение было неопределённым (Undefined Behavior), хотя большинство реализаций также обрабатывали это безопасно. Для полной переносимости в старом коде иногда делали проверку if (ptr) delete ptr;.
  2. Двойное удаление (double delete) — это всегда UB, даже если первый вызов был на nullptr.
    int* p = new int(42);
    delete p; // Освобождает память
    p = nullptr; // Обнуляем указатель
    delete p; // Безопасно, ничего не делает (p == nullptr)
    // НО:
    delete p; // Второй вызов delete на том же нулевом указателе — всё ещё безопасный no-op.
  3. Это правило работает только для стандартного оператора delete. Для пользовательских функций освобождения памяти (placement delete, custom deallocators) поведение определяется их реализацией.