このタイプのメモリは、ヒープまたはスタックに割り当てられますか?

StackOverflow https://stackoverflow.com/questions/426737

質問

C ++のコンテキスト(重要ではない):

class Foo{
    private:
        int x[100];
    public:
        Foo();
}

私が学んだことから、Fooのインスタンスを次のように作成すると、

Foo bar = new Foo();

次に、配列xがヒープに割り当てられますが、Fooのインスタンスを次のように作成した場合:

Foo bar;

その後、スタック上に作成されます。

これを確認するためのリソースがオンラインで見つかりません。

役に立ちましたか?

解決

例を少し変更してください:

class Foo{
    private:
        int x[100];
        int *y;
    public:
        Foo()
        {
           y = new int[100];
        }
        ~Foo()
        { 
           delete[] y; 
        }

}

例1:

Foo *bar = new Foo();
  • xとyはヒープ上にあります:
  • sizeof(Foo *)がスタック上に作成されます。
  • sizeof(int)* 100 * 2 + sizeof(int *)はヒープ上にあります

例2:

Foo bar;
  • xはスタック上にあり、yはヒープ上にあります
  • sizeof(int)* 100はスタック上にある(x)+ sizeof(int *)
  • sizeof(int)* 100はヒープ上(y)

実際のサイズは、コンパイラーとプラットフォームに応じて、クラス/構造体のアライメントにより若干異なる場合があります。

他のヒント

厳密に言えば、標準によれば、オブジェクトはスタックまたはヒープ上に存在する必要はありません。標準では、3種類の「ストレージ期間」が定義されていますが、ストレージの実装方法を正確には規定していません。

  1. 静的保存期間
  2. 自動保存期間
  3. 動的ストレージ期間

通常、自動ストレージ期間はスタックを使用して(ほぼ常に)実装されます。

動的ストレージ期間は通常、ヒープを使用して実装されます(最終的には malloc()を使用)。ただし、これはコンパイラのユーザーでも上書きできます。

静的ストレージ期間は、一般的にグローバル(または静的ストレージ)と呼ばれるものです。

標準では、これらのことについて述べています(以下は、3.7のさまざまなビットからの抜粋です-ストレージ期間):

  

静的および自動保存期間   導入されたオブジェクトに関連付けられている   宣言(3.1)および暗黙的に   実装によって作成されました(12.2)。   動的ストレージ期間は   で作成されたオブジェクトに関連付けられています   演算子new(5.3.4)。

     

...

     

動的ではないすべてのオブジェクト   保存期間もローカルもありません   静的ストレージ期間。ストレージ   これらのオブジェクトは   プログラムの期間(3.6.2、   3.6.3)。

     

...

     

autoが明示的に宣言されたローカルオブジェクト   または登録するか、明示的に宣言しない   staticまたはexternには自動   保管期間。のストレージ   これらのオブジェクトは、ブロックが   それらは出口で作成されます。

     

...

     

オブジェクトは動的に作成できます   プログラム実行中(1.9)、使用   new-expressions(5.3.4)、および破棄   delete-expressions(5.3.5)を使用します。交流   + +実装により、動的ストレージへのアクセスと管理を提供します。   グローバル割り当て関数   operator newおよびoperator new []および   グローバルな割り当て解除関数   operator deleteおよびoperator delete []。

     

...

     

ライブラリはデフォルトを提供します   グローバル割り当ての定義   および割り当て解除関数。一部   グローバルな割り当てと割り当て解除   関数は交換可能です(18.4.1)

そして最後に(例のクラスの配列に関して):

  

3.7.4サブオブジェクトの期間[basic.stc.inherit]

     

メンバーサブオブジェクト、ベースクラスサブオブジェクト、および配列要素の保存期間は、それらの完全な保存期間です   オブジェクト(1.8)。

Foo型のオブジェクトは、順番に格納された100 intのサイズを取ります。 スタック上に作成すると、すべてスタック上に作成されます。 newで実行すると、オブジェクトの一部としてヒープ上に配置されます。

これは言語仕様の一部です。あなたの質問が何であるかわかりません。

はい、ヒープに Foo オブジェクトを作成すると、ヒープにメンバー配列 x が作成されます。 Foo に動的メモリを割り当てるとき、長さ sizeof(Foo)のメモリを要求しています(さらにメモリオーバーヘッドも可能ですが、とりあえずそれを無視しましょう)。サンプルコードでは、100個の int sのサイズを示しています。この は、 Foo 型のオブジェクト(およびその内部データ)の寿命がスコープを超えている場合に当てはまります。

ヒープに Foo オブジェクトを作成せず、 Foo の内部配列がでメモリを割り当てるポインタではない場合 Foo のコンストラクタでnew を指定すると、その内部配列がスタック上に作成されます。繰り返しますが、これは、スコープが終了したときに delete sなしで配列が自動的にクリーンアップされるためです。具体的には、

struct Foo {
    int* y;
    Foo() : y(new int()) { }
    ~Foo() { delete y; }
};

は、 Foo オブジェクトがスタック上またはヒープ上に作成されたかどうかに関係なく、ヒープ上に y を作成します。

という意味

Foo* bar = new Foo(); 

そうですね。ヒープ内にそれが作成されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top