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式 によって割り当てられたオブジェクトを破棄し、取得したメモリ領域を解放します。

目次

構文

:: (オプション) delete (1)
:: (オプション) delete[] (2)
expression - 以下のいずれか:
1) new-expression によって作成された1つの非配列オブジェクトを破棄します。
2) new[]-expression によって作成された配列を破棄します。

説明

expression から評価されたポインタ(変換が行われる可能性あり)を ptr として与えられた場合。

1) ptr は以下のいずれかでなければならない:
  • ヌルポインタ
  • new-expression によって作成された非配列オブジェクトへのポインタ
  • new-expression によって作成された非配列オブジェクトの基底サブオブジェクトへのポインタ
ptr が指す型は、オブジェクトの型(または基底サブオブジェクトの型)と similar でなければなりません。 ptr がそれ以外の場合、例えば new-expression の配列形式で取得されたポインタである場合も含め、その動作は undefined です。
2) ptr must be a null pointer or a pointer whose value is previously obtained by an array form of new-expression whose allocation function was not a non-allocating form (i.e. overload (10) ).
ptr が指す型は、配列オブジェクトの要素型と similar でなければなりません。 ptr がそれ以外の場合、例えば new-expression の非配列形式で取得されたポインタである場合を含め、その動作は undefined です。

delete式の結果の型は常に void です。

削除されるオブジェクトが不完全なクラス型である場合、 完全なクラスが非トリビアルなデストラクタまたは解放関数を持つとき、動作は未定義 (C++26まで) プログラムは不適格 (C++26以降)

ptr が null ポインタでない場合 かつ 解放関数 が destroying delete でない場合 (C++20以降) 、delete式は破棄されるオブジェクトの デストラクタ (存在する場合)、または破棄される配列の各要素のデストラクタ(配列の最後の要素から最初の要素に向かって順に)を呼び出す。デストラクタはdelete式が現れる位置から アクセス可能 でなければならない。

その後、例外がどのデストラクタによってスローされたかどうかに関わらず、delete式は デアロケーション関数 を呼び出します: operator delete (第1バージョン)または operator delete [ ] (第2バージョン)のいずれかです 、ただし、対応するnew式が別のnew式と組み合わされていた場合を除きます (since C++14)

デアロケーション関数の名前は、 ルックアップ ptr によって指されるオブジェクトの動的型のスコープで行われます。これは、クラス固有のデアロケーション関数が存在する場合、グローバルなものよりも先に見つかることを意味します。delete式に :: が存在する場合、このルックアップではグローバル名前空間のみが調べられます。いずれの場合も、通常のデアロケーション関数以外の宣言は破棄されます。

いずれかの解放関数が見つかった場合、呼び出す関数は以下のように選択されます(これらの関数とその効果に関する詳細な説明については 解放関数 を参照してください):

  • 解放関数のうち少なくとも一つが破壊的deleteである場合、すべての非破壊的deleteは無視されます。
(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 で確保されたオブジェクトの基底クラス部分オブジェクトへのポインタである場合、基底クラスのデストラクタは virtual でなければならず、そうでない場合の動作は未定義です。

注記

void へのポインタは、オブジェクト型へのポインタではないため削除できません。

delete キーワードの直後に角括弧のペアが続く場合、常にdelete式の配列形式として解釈されるため、 ラムダ式 が空のキャプチャリストを持ち、かつ delete の直後に記述される場合は、必ず括弧で囲む必要があります。

// delete []{ return new int; }(); // 解析エラー
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 がポインタ左辺値になり得た 許可されない
CWG 2474 C++98 類似しているが異なる型のオブジェクトへの
ポインタを削除すると未定義動作となった
明確に定義された動作とする
CWG 2624 C++98 非割り当て
operator new [ ] から取得したポインタを delete [ ] に渡せた
禁止
CWG 2758 C++98 解放関数とデストラクタに対する
アクセス制御の方法が不明確だった
明確化

関連項目