4

重複の可能性:
動的に割り当てられた配列を解放するためにdelete(delete [])で[]が使用されるのはなぜですか?
C ++にまだdelete[]とdelete演算子があるのはなぜですか?

私はそれらの違いが何であるか疑問に思っています、そして私はいくつかが言うかもしれない明白な答えを知っています、1つは配列を削除することであり、もう1つは単一のオブジェクトを削除することですが、なぜこれらの2つの操作に2つの異なる削除方法があるべきなのか疑問に思います?つまり、 deleteは基本的にfree、ポインタが実際に配列を指しているのか単一のオブジェクトを指しているのかを気にしないCメソッドを使用して実装されます。私が考えることができる唯一の理由は、それが配列であるかどうかを知ることができ、最初のオブジェクトだけでなく各セルのデストラクタを呼び出すことができるということですが、コンパイラは配列を見ているだけでは配列の長さを推測できないため、それも不可能です。ポインタ。ちなみに、未定義動作を呼び出しdeleteて、割り当てられたメモリを呼び出すと言われていますnew[]が、

4

3 に答える 3

3

あなたが発見したように、コンパイラは、各要素のデストラクタを呼び出すことができるように、配列の長さを知る必要があります(少なくとも非自明な型の場合)。このため、通常、new[] は追加のバイトを割り当てて要素数を記録し、このブックキーピング領域の末尾へのポインターを返します。

delete[] を使用すると、コンパイラは配列の前のメモリを調べてカウントを見つけ、ポインターを調整するため、最初に割り当てられたブロックが解放されます。

delete動的に割り当てられた配列を破棄するために使用すると、要素 (最初のものを除く) のデストラクタは呼び出されず、通常、割り当てられたブロックの先頭を指していないポインタを解放しようとすることになり、破損する可能性があります。ヒープ。

于 2013-01-27T23:06:44.233 に答える
1

しかし、コンパイラはポインタを見ただけでは配列の長さを推測できないため、それも可能ではありません

それは本当ではありません。コンパイラ自体は何も推測する必要はありませんが、確認した演算子に基づいてメモリを解放するために呼び出す関数を決定します。配列の解放専用の別の関数があり、この関数は実際に解放される配列の長さを認識しているため、デストラクタを適切に呼び出すことができます。

通常new[]、配列の長さを含むメモリを割り当て (これは割り当て時にわかっているため)、割り当てられた「使用可能な」メモリだけへのポインタを返すため、配列の長さを知っています。がdelete[]呼び出されると、指定された配列の使用可能な部分へのポインタに基づいて、このメモリにアクセスする方法を認識します。

于 2013-01-27T23:01:16.920 に答える
0

を使用してメモリを割り当てる場合new[]、コンパイラは各要素を構築する必要があるだけでなく、割り当てられた要素の数を追跡する必要もあります。これは、delete[]正しく動作するために必要です。

newとはスカラーを操作するためdelete、それを行う必要はなく、オーバーヘッドを少し節約できます。

newがと互換性がある必要はなくdelete[]、その逆もありません。2 つを混在させると、未定義の動作になります。

于 2013-01-27T23:01:31.573 に答える