web-dev-qa-db-ja.com

C ++のdelete vs delete []演算子

C++のdelete演算子とdelete[]演算子の違いは何ですか?

106
shreyasva

delete演算子はメモリの割り当てを解除し、newで作成された単一オブジェクトのデストラクタを呼び出します。

delete []演算子はメモリの割り当てを解除し、new []で作成されたオブジェクトの配列のデストラクターを呼び出します。

new []によって返されるポインターでdeleteを使用するか、newによって返されるポインターでdelete []を使用すると、未定義の動作が発生します。

125
Nick Meyer

_delete[]_演算子は、配列を削除するために使用されます。 delete演算子は、非配列オブジェクトを削除するために使用されます。 _operator delete[]_および_operator delete_関数をそれぞれ呼び出して、配列の要素または非配列オブジェクトのデストラクターを(最終的に)呼び出した後に、配列または非配列オブジェクトが占有していたメモリを削除します。

以下に関係を示します。

_typedef int array_type[1];

// create and destroy a int[1]
array_type *a = new array_type;
delete [] a;

// create and destroy an int
int *b = new int;
delete b;

// create and destroy an int[1]
int *c = new int[1];
delete[] c;

// create and destroy an int[1][2]
int (*d)[2] = new int[1][2];
delete [] d;
_

配列を作成するnewの場合(つまり、_new type[]_またはnewが配列型の構成体に適用される)、標準は配列の_operator new[]_を探します要素タイプクラスまたはグローバルスコープで、要求されたメモリ量を渡します。必要に応じてN * sizeof(ElementType)より多くを要求する場合があります(たとえば、要素の数を格納するため、後で削除するときに実行されるデストラクター呼び出しの数がわかります)。クラスが_operator new[]_を宣言し、そのメモリ量に追加で別の_size_t_を受け入れる場合、その2番目のパラメーターは割り当てられた要素の数を受け取ります-目的(デバッグなど)にこれを使用できます。 ..)。

非配列オブジェクトを作成するnewの場合、要素のクラスまたはグローバルスコープで_operator new_を探します。要求されたメモリ量を渡します(常にsizeof(T)常に)。

_delete[]_の場合、配列の要素クラス型を調べて、デストラクタを呼び出します。使用される_operator delete[]_関数は、要素タイプのクラスにあるか、グローバルスコープにない場合です。

deleteの場合、渡されるポインターが実際のオブジェクトの型の基本クラスである場合、基本クラスには仮想デストラクタが必要です(そうでない場合、動作は未定義です)。基本クラスではない場合、そのクラスのデストラクタが呼び出され、そのクラスの_operator delete_またはグローバル_operator delete_が使用されます。基本クラスが渡された場合、実際のオブジェクト型のデストラクタが呼び出され、そのクラスで見つかった_operator delete_が使用されます。存在しない場合は、グローバル_operator delete_が呼び出されます。クラスの_operator delete_に_size_t_型の2番目のパラメーターがある場合、割り当てを解除する要素の数を受け取ります。

これは、c ++のallocate/DE-allocateパターンの基本的な使用法ですmalloc/free、new/delete、new []/delete []

それらを適切に使用する必要があります。しかし、deleteとdelete []の違いについて、この特定の理解を追加したいと思います。

1)delete単一オブジェクトに割り当てられたメモリの割り当てを解除するために使用されます

2)delete []は、オブジェクトの配列に割り当てられたメモリの割り当てを解除するために使用されます

クラスABC {}

ABC * ptr =新しいABC [100]

new [100]と言うとき..コンパイラーは、割り振る必要があるオブジェクトの数(ここでは100)に関する情報を取得でき、作成された各オブジェクトのコンストラクターを呼び出します。

しかし、この場合に単にdelete ptrを使用すると、コンパイラはptrが指しているオブジェクトの数を知らず、デストラクタの呼び出しとメモリの削除のみを行うことになります1オブジェクト(デストラクタの呼び出しと残りの99オブジェクトの割り当て解除を残します)。したがって、メモリリークが発生します

したがって、この場合はdelete [] ptrを使用する必要があります。

13
ravs2627

演算子deleteおよびdelete []は、それぞれnewおよびnew[]で作成されたオブジェクトを破棄するために使用され、コンパイラのメモリマネージャーで使用可能な割り当てメモリに戻ります。

newで作成されたオブジェクトは、必ずdeleteで破棄する必要があり、new[]で作成した配列はdelete[]で削除する必要があります。

4
san983

この質問をしたときの本当の質問は、「両者に違いはありますか?ランタイムは配列サイズに関する情報を保持する必要はないので、どちらを意味するのかわかりませんか?」です。この質問は「関連する質問」には現れないので、私のような人を助けるために、その答えを以下に示します。 "なぜdelete []演算子が必要なのですか?"

1
Ekalavya