9

次のコードは何をしますか?

obj *x = new obj[100];
delete x; // Note the omission of []

配列の最初の要素のみを削除しますか?

4

3 に答える 3

11

上記のコードは未定義の動作を示しています。

delete[] x;

割り当てはで行われたためnew[]です。

正しい演算子を使用すると、ポインターが指す配列全体が削除されます。

obj *x = new obj[100];
delete[] x; // The entire array gets deleted
于 2012-10-08T10:14:44.703 に答える
9

未定義の動作ですが、おそらく最も可能性の高い結果に注意する必要があります(このような問題をデバッグするため)。

を介して配列を作成すると、new Object[100]最初にメモリが割り当てられます。デフォルトの動作(デフォルトのアロケータにオーバーライドがない場合)は、単にを呼び出すことmalloc(100 * sizeof(Object))です。その後、各サイズのリージョンでのコンストラクターをObject呼び出す必要があります。Objectこれは重要な詳細です。メモリは一度割り当てられますが、コンストラクタは100か所で呼び出されます。

ブロックがを介して割り当てられる場合、ブロックmallocを分割して解放することはできません。を呼び出すだけで、free(block)そのメモリが解放されます。C ++キーワードは、キーワードがを呼び出す場合、delete内部的に呼び出します。したがって、配列を削除する適切な方法は、を呼び出すことです。では、電話するとどうなりますか?考えられる答えは、メモリが解放される(最初の要素だけでなく、すべて)が、1つのデストラクタ(最初の要素のデストラクタ)のみが呼び出されるというものです。freenewmallocdelete [] arraydelete array

明らかに、考慮すべき事実はたくさんあります。newdeleteにバインドされている必要はありませmallocfree。特定のアーキテクチャまたはオペレーティングシステムに固有のシステムコールを使用する場合があります。(特に、Windowsには、C APIの外部mallocおよび内部にヒープ管理機能のセット全体があります。)コードをステップ実行するときに最も頻繁に見たのは、とを使用した例です。たとえば、Visual Studioを使用すると、呼び出しにステップインして、実際に関数コードを確認できます。(これはもう1つの重要な詳細です。これは単なる関数呼び出しであり、多くの場合、オーバーライドすることもできます。)freemallocfreenewnewnewdelete


この小さなプログラムでこの概念を示すことができます。Objectコンストラクター中に何かを出力し、デストラクタ中に何か他のものを出力するクラスを作成するだけです。

int main(int argc, char** argv)
{
    Object* o = new Object[4];
    delete o;
    return 0;
}

私はそれを実行しました、そして確かに:コンストラクターは4回呼び出され、デストラクタは1回呼び出されました。

于 2012-10-08T16:04:04.640 に答える
-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;
}
于 2012-10-08T14:25:34.957 に答える