оператор delete
Удаляет объект(ы), ранее выделенный(ые) оператором new, и освобождает полученную область памяти.
Синтаксис
::(необязательно) delete выражение |
(1) | |
::(необязательно) delete[] выражение |
(2) |
| выражение | - | одно из следующих:
|
Объяснение
Учитывая указатель, полученный из выражения (после возможных преобразований), как ptr.
ptr должен быть одним из
- нулевым указателем,
- указателем на объект, не являющийся массивом, созданный оператором new, или
- указателем на базовую подобъект объекта, не являющегося массивом, созданный оператором new.
ptr должен быть совместимым с типом объекта (или его базовой подобъект). Если ptr имеет другое значение, включая если это указатель полученный с помощью массива формы оператора new, поведение является неопределённым.ptr должен быть нулевым указателем или указателем, полученным ранее с помощью массива формы оператора new[], чья функция выделения памяти функция выделения памяти не является невыделяющей (т.е. перегрузка (10)).ptr должен быть совместимым с типом элементов массива. Если ptr имеет другое значение, включая если это указатель полученный с помощью не-массива формы оператора new, поведение является неопределённым.Результат оператора delete всегда имеет тип void.
Если объект, подлежащий удалению, имеет неполный тип класса на момент удаления, и полный класс имеет нетривиальный деструктор или функцию освобождения, поведение является неопределенным.
Если ptr не является нулевым указателем и функция освобождения функция освобождения не является деструктирующим delete(с C++20), оператор delete вызывает деструктор (если есть) для объекта, который уничтожается, или для каждого элемента массива, который уничтожается (происходит от последнего элемента к первому элементу массива).
После этого, независимо от того, было ли выброшено исключение каким-либо деструктором, оператор delete вызывает функцию освобождения функцию освобождения: либо operator delete (первая версия) или operator delete[] (вторая версия), если соответствующее выражение new было объединено с другим выражением new(с C++14).
Имя функции освобождения ищется в области видимости динамического типа объекта, на который указывает ptr, что означает, что функции освобождения, специфичные для класса, если они присутствуют, находятся перед глобальными. Если :: присутствует в операторе delete, только глобальное пространство имён исследуется в ходе этого поиска. В любом случае, любые объявления, кроме обычных функций освобождения, отбрасываются.
Если поиск находит более одной функции освобождения, функция, которая должна быть вызвана, выбирается следующим образом (см. функцию освобождения для более подробного описания этих функций и их эффектов):
|
(с C++20) |
|
(с C++17) |
- Если найденные функции освобождения специфичны для класса, функция освобождения класса, не учитывающая размер (без параметра типа
std::size_t), предпочтительнее функции освобождения класса, учитывающей размер (с параметром типаstd::size_t).
|
(с C++14) |
Указатель на блок памяти, который должен быть освобождён, передаётся в функцию освобождения, выбранную выше, как первый аргумент. Размер блока передаётся как необязательный std::size_t аргумент. Требование выравнивания передаётся как необязательный std::align_val_t аргумент.(с C++17)
Если ptr является нулевым указателем, деструкторы не вызываются, а функция освобождения может или не может быть вызвана (не определено), но гарантируется, что стандартные функции освобождения ничего не делают, когда им передаётся нулевой указатель.
Если ptr является указателем на подобъект базового класса объекта, который был выделен с помощью new, деструктор базового класса должен быть виртуальным, в противном случае поведение является неопределенным.
Примечания
Указатель на void не может быть удалён, так как он не является указателем на полный тип объекта.
|
Поскольку пара скобок, следующая за ключевым словом delete, всегда интерпретируется как массивная форма оператора delete, лямбда-выражение с пустым списком захвата сразу после delete должно быть заключено в скобки. // delete []{ return new int; }(); // parse error
delete ([]{ return new int; })(); // OK |
(с C++11) |
Ключевые слова
Отчёты о дефектах
Следующие отчёты о дефектах, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение, как опубликовано | Правильное поведение |
|---|---|---|---|
| CWG 288 | C++98 | для первой формы, статический тип операнда сравнивался с его динамическим типом | сравнивается статический тип объекта, подлежащего удалению, с его динамическим типом |
| CWG 353 | C++98 | не было определено, будет ли вызвана функция освобождения, если деструктор выбросит исключение | всегда вызывается |
| CWG 599 | C++98 | первая форма могла принять нулевой указатель любого типа, включая указатели на функции | кроме указателей на типы объектов, все другие типы указателей отклоняются |
| CWG 1642 | C++98 | выражение могло быть указателем-lvalue | не разрешается |
| CWG 2474 | C++98 | удаление указателя на объект сходного, но разного типа приводило к неопределённому поведению | сделано хорошо определённым |
| CWG 2624 | C++98 | указатели, полученные от невыделяющей operator new[], могли быть переданы delete[] | запрещено |
См. также
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/delete