delete expression
Уничтожает объект(ы), ранее выделенные с помощью new-expression и освобождает полученную область памяти.
Содержание |
Синтаксис
::
(необязательно)
delete
выражение
|
(1) | ||||||||
::
(необязательно)
delete[]
выражение
|
(2) | ||||||||
| expression | - |
один из следующих вариантов:
|
Объяснение
Указатель, полученный из expression (после возможных преобразований) как ptr .
- нулевым указателем,
- указателем на не-массивный объект, созданный с помощью new-expression , или
- указателем на базовый подобъект не-массивного объекта, созданного с помощью new-expression .
Результат выражения delete всегда имеет тип void .
Если удаляемый объект имеет неполный тип класса в точке удаления, и полный класс имеет нетривиальный деструктор или функцию освобождения памяти, поведение не определено (до C++26) программа является некорректной (начиная с C++26) .
Если ptr не является нулевым указателем и функция освобождения памяти deallocation function не является destroying delete (since C++20) , выражение delete вызывает destructor (если он существует) для уничтожаемого объекта или для каждого элемента уничтожаемого массива (начиная с последнего элемента до первого элемента массива). Деструктор должен быть accessible из точки, где находится выражение delete.
После этого, независимо от того, было ли исключение вызвано каким-либо деструктором, выражение delete вызывает функцию освобождения памяти : либо operator delete (первая версия), либо operator delete [ ] (вторая версия) , если только соответствующее выражение new не было объединено с другим выражением new (since C++14) .
Имя функции освобождения памяти
ищется
в области видимости динамического типа объекта, на который указывает
ptr
, что означает, что специфичные для класса функции освобождения, если они присутствуют, находятся раньше глобальных. Если
::
присутствует в delete-expression, этим поиском исследуется только глобальное пространство имён. В любом случае, все объявления, кроме обычных функций освобождения, отбрасываются.
Если найдена любая функция освобождения памяти, функция для вызова выбирается следующим образом (см. deallocation function для более подробного описания этих функций и их эффектов):
|
(since C++20) |
|
(since C++17) |
- Если найденные функции освобождения являются специфичными для класса, то специфичная для класса функция освобождения без учёта размера (без параметра типа std::size_t ) предпочтительнее специфичной для класса функции освобождения с учётом размера (с параметром типа std::size_t ).
|
(начиная с C++14) |
Выбранная функция освобождения памяти должна быть доступна из точки, где появляется delete-выражение, за исключением случая, когда функция освобождения выбирается в точке определения динамического типа ’s виртуального деструктора .
Указатель на блок памяти, который должен быть освобожден, передается в функцию деаллокации , выбранную в процессе выше, в качестве первого аргумента. Размер блока передается в качестве опционального std::size_t аргумента. Требование выравнивания передается в качестве опционального std::align_val_t аргумента. (since C++17)
Если ptr является нулевым указателем, деструкторы не вызываются, и функция освобождения памяти может быть вызвана или не вызвана (это не определено), но стандартные функции освобождения гарантированно не выполняют никаких действий при передаче нулевого указателя.
Если ptr является указателем на подобъект базового класса объекта, который был выделен с помощью new , деструктор базового класса должен быть virtual , иначе поведение не определено.
Примечания
Указатель на void не может быть удалён, поскольку он не является указателем на объектный тип.
|
Поскольку пара квадратных скобок после ключевого слова delete всегда интерпретируется как форма удаления массива, лямбда-выражение с пустым списком захвата, расположенное сразу после delete , должно быть заключено в круглые скобки. // delete []{ return new int; }(); // ошибка парсинга delete ([]{ return new int; })(); // OK |
(начиная с C++11) |
Ключевые слова
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| CWG 288 | C++98 |
for the first form, the static type of the
operand was compared with its dynamic type |
compare the static type of the object
to be deleted with its dynamic type |
| CWG 353 | C++98 |
whether the deallocation function will be invoked if
the destructor throws an exception was unspecified |
always invoked |
| CWG 599 | C++98 |
the first form could take a null pointer of
any type, including function pointers |
except pointers to object types,
all other pointer types are rejected |
| CWG 1642 | C++98 | expression could be a pointer lvalue | not allowed |
| CWG 2474 | C++98 |
deleting a pointer to an object of a similar but
different type resulted in undefined behavior |
made well-defined |
| CWG 2624 | C++98 |
pointers obtained from non-allocating
operator new [ ] could be passed to delete [ ] |
prohibited |
| CWG 2758 | C++98 |
it was unclear how access control was done for
the deallocation function and the destructor |
made clear |