Spec-Zone.ru › C++

оператор delete

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

Синтаксис

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

Объяснение

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

1) ptr должен быть одним из
  • нулевым указателем,
  • указателем на объект, не являющийся массивом, созданный оператором new, или
  • указателем на базовую подобъект объекта, не являющегося массивом, созданный оператором new.
Тип указываемого объекта ptr должен быть совместимым с типом объекта (или его базовой подобъект). Если ptr имеет другое значение, включая если это указатель полученный с помощью массива формы оператора new, поведение является неопределённым.
2) ptr должен быть нулевым указателем или указателем, полученным ранее с помощью массива формы оператора new[], чья функция выделения памяти функция выделения памяти не является невыделяющей (т.е. перегрузка (10)).
Тип указываемого объекта ptr должен быть совместимым с типом элементов массива. Если ptr имеет другое значение, включая если это указатель полученный с помощью не-массива формы оператора new, поведение является неопределённым.

Результат оператора delete всегда имеет тип void.

Если объект, подлежащий удалению, имеет неполный тип класса на момент удаления, и полный класс имеет нетривиальный деструктор или функцию освобождения, поведение является неопределенным.

Если ptr не является нулевым указателем и функция освобождения функция освобождения не является деструктирующим delete(с C++20), оператор delete вызывает деструктор (если есть) для объекта, который уничтожается, или для каждого элемента массива, который уничтожается (происходит от последнего элемента к первому элементу массива).

После этого, независимо от того, было ли выброшено исключение каким-либо деструктором, оператор delete вызывает функцию освобождения функцию освобождения: либо operator delete (первая версия) или operator delete[] (вторая версия), если соответствующее выражение new было объединено с другим выражением new(с C++14).

Имя функции освобождения ищется в области видимости динамического типа объекта, на который указывает ptr, что означает, что функции освобождения, специфичные для класса, если они присутствуют, находятся перед глобальными. Если :: присутствует в операторе delete, только глобальное пространство имён исследуется в ходе этого поиска. В любом случае, любые объявления, кроме обычных функций освобождения, отбрасываются.

Если поиск находит более одной функции освобождения, функция, которая должна быть вызвана, выбирается следующим образом (см. функцию освобождения для более подробного описания этих функций и их эффектов):

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

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

delete

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

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

См. также

  • new

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/delete

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API