Namespaces
Variants

delete expression

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
delete expression
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Уничтожает объект(ы), ранее выделенные с помощью new-expression и освобождает полученную область памяти.

Содержание

Синтаксис

:: (необязательно) delete выражение (1)
:: (необязательно) delete[] выражение (2)
expression - один из следующих вариантов:
1) Уничтожает один не-массивный объект, созданный с помощью new-expression .
2) Уничтожает массив, созданный с помощью new[]-выражения .

Объяснение

Указатель, полученный из expression (после возможных преобразований) как ptr .

1) ptr должен быть одним из следующих:
  • нулевым указателем,
  • указателем на не-массивный объект, созданный с помощью new-expression , или
  • указателем на базовый подобъект не-массивного объекта, созданного с помощью new-expression .
Тип, на который указывает ptr , должен быть подобен типу объекта (или базового подобъекта). Если ptr представляет собой что-либо иное, включая указатель, полученный через массивную форму new-expression , поведение является неопределённым .
2) ptr должен быть нулевым указателем или указателем, значение которого было ранее получено с помощью формы массива new-expression , чья allocation function не была не-аллоцирующей формой (т.е. перегрузка (10) ).
Тип, на который указывает ptr , должен быть подобен типу элемента массива. Если ptr является чем-либо иным, включая указатель, полученный не-массивной формой 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)
  • Если требование выравнивания типа превышает __STDCPP_DEFAULT_NEW_ALIGNMENT__ , предпочтение отдается функциям освобождения с учетом выравнивания (с параметром типа std::align_val_t ). Для других типов предпочтение отдается функциям освобождения без учета выравнивания (без параметра типа std::align_val_t ).
  • Если найдено более одной предпочтительной функции, только предпочтительные функции рассматриваются на следующем шаге.
  • Если предпочтительные функции не найдены, на следующем шаге рассматриваются непредпочтительные.
  • Если остается только одна функция, она выбирается.
(since C++17)
  • Если найденные функции освобождения являются специфичными для класса, то специфичная для класса функция освобождения без учёта размера (без параметра типа std::size_t ) предпочтительнее специфичной для класса функции освобождения с учётом размера (с параметром типа std::size_t ).
  • В противном случае поиск достигает глобальной области видимости, и:
  • Если тип является полным и если, только для формы массива, операнд является указателем на класс с нетривиальным деструктором или (возможно, многомерным) массивом таких классов, выбирается глобальная функция освобождения с учетом размера (с параметром типа std::size_t ).
  • В противном случае не определено, выбирается ли глобальная функция освобождения с учетом размера (с параметром типа 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)

Ключевые слова

delete

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам 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

Смотрите также