2

違いは何ですか

Kwadrat* k1 = new Kwadrat(1,2,3);
k1->field = 0;
Kwadrat k2(1,2,3);
k2.field = 0;

最初のものは割り当てられたメモリへのポインターであり、2番目のものはオブジェクトです(システムスタックのどこにありますか?) 2番目はなぜ悪いのですか? 最初に使用するとき、2 番目のものはいつ使用しますか?

4

4 に答える 4

2

ヒープ上での動的割り当て ( を使用new):
Kwadrat* k1 = new Kwadrat(1,2,3);
スタック上でのオブジェクト作成 ( なしnew):
Kwadrat k2(1,2,3);

スタックとヒープに関する詳細な議論については、このスタック オーバーフローの質問を確認してください。ブライアン R. ボンディの回答は 2 つを比較する優れた仕事をしますが、ジェフ ヒルの回答はさらに重要な詳細を提供します。

危険なほど小さな要約の場合:

  • deleteで作成したオブジェクトを使用する必要があります。newそうしないと、コードでメモリ リークが発生します。
  • C++ Resource Allocation is Initialization (RAII)によって処理されるため、スタック上に作成されたオブジェクトを手動で削除することを心配する必要はありません。
  • 非常に大きな割り当てを試みると、スタックがオーバーフローする可能性があります。
  • どちらを使用するかは、作成するオブジェクトの意図した範囲によって異なります
于 2012-08-10T15:56:36.723 に答える
2

new を使用すると、ヒープ上にオブジェクトが動的に作成されます。つまり、ポインター (k1*) がスコープ外に出てもオブジェクトは保持されます。

これは便利な場合がありますが、範囲外になり、ポインタのコピーを保持しないと、永久に失われ、メモリ リークが発生します。これは、プログラムが実行されている限り、そのリソースが使用するスペースを失うことを意味します。これは、new を使用してメモリを動的に割り当てることの欠点です。追跡し、delete 演算子を使用して手動で解放する必要がありますが、これには余分な作業が必要です。

他の方法で行うと、スコープを離れると破棄されるスタックオブジェクトが作成されます。これは通常望ましいことです。

多くの場合、new で動的メモリ作成を使用する場合、動的に作成されたオブジェクトを別のオブジェクトでラップすることにより、このスタックのような機能を取得しようとします。このオブジェクトは、スコープ外になると破棄されます。このパターンはResource Acquisition is Initialization (RAII)と呼ばれます。これは、オブジェクトをスコープ外に永続化できるため、参照カウントで最も役立ちますが、オブジェクトを参照するものがなくなると破棄されます。

于 2012-08-10T15:57:39.410 に答える
0

new はヒープにオブジェクトを割り当てます。2 番目の例では、スタックにメモリを割り当てます。k2 を割り当てた関数が返されるとすぐに、メモリは有効ではなくなります (もちろん、k2 のデストラクタが最初に呼び出されます)。オブジェクトを作成した関数よりも長く存続させたい場合は、 new を使用する必要があります。

于 2012-08-10T15:57:03.360 に答える
0

new要求する割り当てのストレージを指定できます。経由の割り当てnew/new[]は通常ヒープ上にありますが (例: ラッピングmalloc)、最終的には実装によって定義されます。同様に、コンパイラは、場合によってはこれをバイパスするのに十分な情報を持っている可能性があります。

システムスタックのどこにありますか?

技術的には、通常、抽象マシンの仕様に合わせて C++ を記述します。

しかし、通常、はい - オブジェクトはスレッドのスタックに割り当てられます。

なぜ2番目が悪いのですか?最初に使用するとき、2 つ目を使用するときは?

2番目は非常に明確であるため、デフォルトにする必要があります。コンパイラはその寿命と割り当てを管理し、非常に高速です。これに対するいくつかの例外は次のとおりです。

  • 割り当てが大きい場合 (スタック サイズが比較的小さい)
  • 割り当てを別のスレッドと共有したい場合があります
  • 割り当てを別のスレッドに渡したいとき
  • メソッドのスコープを超えてオブジェクトを存続させたい場合、通常はオブジェクトを適切に削除するスマート ポインターまたはその他のコンテナーを使用します。

要するに、(2 番目の方法を使用すると) 失敗する可能性がはるかに少なくなり、汎用システム アロケーターを介して割り当てを作成するのに費やされる時間が大幅に短縮されます。

于 2012-08-10T15:57:48.363 に答える