2012-01-20 15 views
2

例えば、私は次のようにメモリを割り当てたとき、私は状況を可視化することができます。メモリ構造(可視化)

Position* arr1 = new Position[5]; 

位置が説明私のプログラム内のクラスであることxとyの値を持つ位置の点。

それは次のようになりますので、ヒープ上のアレイ「ARR1」の最初の要素(ポジションオブジェクト)を指すスタック上のポインタがあるでしょう:どのように

enter image description here

私はポインタの配列を作成していた場合それは見えるだろうか?たとえば:

Position** arr2 = new Position* [2]; 

arr[0] = new Position(3, 7); // Constructs a point with x and y values. 
arr[1] = new Position(9,6); 

全てのポインタとオブジェクトが私の第二の例では、メモリに格納されていますか?スタック上に、ヒープ上のポインタを指すポインタがありますか?ヒープ上のオブジェクトを指していますか?

また、私がdelete [] arr2;になっていた場合、オブジェクトはどこに残っていますか?

ありがとうございました。

答えて

2

1つの自動変数、arr2ポインタオブジェクトがあります。残りはフリーストアにあります。 delete[] arr2のみの場合は、ポイントのオブジェクトではなくポインタのメモリを解放します。

arr2 ---+ +---------------------------------+ 
     | |         | 
     | |         | 
     +----> [Position*, Position*]  | 
      |  |   |    | 
      |  |   +----> [9, 6] | 
      |  v       | 
      | [3, 7]      | 
      +---------------------------------+ 
+0

このフレームをどのようにASCII形式で作成できますか? –

1

配列arr2のポインタがスタック上にあります。他のポインタarr2 [0]、arr2 [1]などはヒープ上にあり、これらのポインタはヒープ上の別の場所を指します。

3
  1. newによって作成されたすべてのオブジェクトは、ヒープ上にあります。したがって、あなたの例では、2つのポインタの配列がヒープ上にあります。 arr2は、ローカル変数としてスタックに格納されます。
  2. newによって別々に割り当てられたPositionオブジェクトは、それぞれ独自のヒープブロックになっています。個別にdelete dにする必要があります。それ以外の場合は、ヒープ上に残ります。オブジェクトはスタックとヒープの間を移動することはできません。 (C++ 11はstd::moveを提供していますが、これは本当に特殊な所有権移転ですが、ヒープアドレスを魔法のようにスタックアドレスに変換するわけではありません)。
  3. delete [] arr2メモリにオブジェクトを残します。ポインタの配列は参照されたオブジェクトを所有していないので、このコードは間接参照されるオブジェクトを破棄するよう要求しません。

あなたは常にコンテナオブジェクト(std::vectorまたはstd::arrayはここで働いてます)、またはそのようなunique_ptrshared_ptrなどのスマートポインタの賛成で直接newdeleteを使用しないようにしてください。

0

ダイアグラムには、レベルの間接化があります。したがって、myArrayarr2と置き換えてください。arr2[0]arr2[1]があります。その後、まだヒープ上にarr2[0]から別の矢印をPosition valueに、arr2[1]を別のPositionに引きます。

delete[] arr2を使用した場合、これらの値は最初に割り当てられたメモリ内のどの位置にも残ります。

+0

あなたのデザインに変更を提案しています。彼のダイアグラムは彼のコードと一致します(最初の例)。 – Potatoswatter

+0

2番目の例を表すためにそれを修正する方法を指摘していました。 – Yuushi