次のコードは何をしますか?
obj *x = new obj[100];
delete x; // Note the omission of []
配列の最初の要素のみを削除しますか?
次のコードは何をしますか?
obj *x = new obj[100];
delete x; // Note the omission of []
配列の最初の要素のみを削除しますか?
上記のコードは未定義の動作を示しています。
delete[] x;
割り当てはで行われたためnew[]
です。
正しい演算子を使用すると、ポインターが指す配列全体が削除されます。
obj *x = new obj[100];
delete[] x; // The entire array gets deleted
未定義の動作ですが、おそらく最も可能性の高い結果に注意する必要があります(このような問題をデバッグするため)。
を介して配列を作成すると、new Object[100]
最初にメモリが割り当てられます。デフォルトの動作(デフォルトのアロケータにオーバーライドがない場合)は、単にを呼び出すことmalloc(100 * sizeof(Object))
です。その後、各サイズのリージョンでのコンストラクターをObject
呼び出す必要があります。Object
これは重要な詳細です。メモリは一度割り当てられますが、コンストラクタは100か所で呼び出されます。
ブロックがを介して割り当てられる場合、ブロックmalloc
を分割して解放することはできません。を呼び出すだけで、free(block)
そのメモリが解放されます。C ++キーワードは、キーワードがを呼び出す場合、delete
内部的に呼び出します。したがって、配列を削除する適切な方法は、を呼び出すことです。では、電話するとどうなりますか?考えられる答えは、メモリが解放される(最初の要素だけでなく、すべて)が、1つのデストラクタ(最初の要素のデストラクタ)のみが呼び出されるというものです。free
new
malloc
delete [] array
delete array
明らかに、考慮すべき事実はたくさんあります。new
とdelete
にバインドされている必要はありませmalloc
んfree
。特定のアーキテクチャまたはオペレーティングシステムに固有のシステムコールを使用する場合があります。(特に、Windowsには、C APIの外部malloc
および内部にヒープ管理機能のセット全体があります。)コードをステップ実行するときに最も頻繁に見たのは、とを使用した例です。たとえば、Visual Studioを使用すると、呼び出しにステップインして、実際に関数コードを確認できます。(これはもう1つの重要な詳細です。これは単なる関数呼び出しであり、多くの場合、オーバーライドすることもできます。)free
malloc
free
new
new
new
delete
この小さなプログラムでこの概念を示すことができます。Object
コンストラクター中に何かを出力し、デストラクタ中に何か他のものを出力するクラスを作成するだけです。
int main(int argc, char** argv)
{
Object* o = new Object[4];
delete o;
return 0;
}
私はそれを実行しました、そして確かに:コンストラクターは4回呼び出され、デストラクタは1回呼び出されました。
このコードはGCCで明確な動作を示していました。つまり、最初のオブジェクトを削除していました。
#include <iostream>
#include <stdlib.h>
#include <time.h>
class myclass {
public:
int i;
myclass(){
std::cout <<"myclass constructed \n";
this->i = rand() % 100;
std::cout<<this->i;
}
~myclass(){
std::cout <<"myclass destroyed\n";
std::cout<<this->i;
}
};
int main()
{
myclass * pt;
srand ( time(NULL) );
pt = new myclass[3];
delete pt;
return 0;
}