4

C++ のコンテキストでは (重要ではありません):

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

私が学んだことは、次のように Foo のインスタンスを作成すると、次のようになります。

Foo bar = new Foo();

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

Foo bar;

次に、スタック上に作成されます。

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

4

5 に答える 5

10

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

  1. 静的保存期間
  2. 自動保存期間
  3. 動的保存期間

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

動的ストレージ期間は通常、ヒープを使用して (最終的には を介し​​てmalloc()) 実装されますが、これはコンパイラのユーザーによってもオーバーライドできます。

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

標準では、これらのことについて次のように述べています (以下は、3.7 のさまざまな部分からの抜粋です - Storage Duration)。

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

...

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

...

auto または register を明示的に宣言したローカル オブジェクト、または static または extern を明示的に宣言していないローカル オブジェクトは、自動ストレージ期間を持ちます。これらのオブジェクトのストレージは、それらが作成されたブロックが終了するまで続きます。

...

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

...

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

そして最後に(サンプルクラスの配列に関して):

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

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

于 2009-01-09T01:53:46.560 に答える
10

あなたの例をわずかに変更すると、次のようになります。

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)

実際のサイズは、コンパイラとプラットフォームによってクラス/構造体の配置が異なるため、わずかに異なる場合があります。

于 2009-01-09T01:39:51.533 に答える
7

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

これは言語仕様の一部です。質問の内容がわかりません。

于 2009-01-09T01:30:16.043 に答える
2

はい、ヒープ上にオブジェクトxを作成すると、メンバー配列がヒープ上に作成されます。Foo動的メモリを割り当てるFooと、長さのメモリが要求されますsizeof(Foo)(さらにメモリ オーバーヘッドが発生する可能性がありますが、当面は無視しましょう)。これは、サンプル コードでは 100int秒のサイズを意味します。これFoo、タイプのオブジェクト(およびその内部データ)の有効期間がスコープをまたがる場合に当てはまります。

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

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

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

于 2009-01-09T01:38:33.843 に答える
1

もしかして

Foo* bar = new Foo(); 

私は考えます。それはヒープに作成されます。

于 2009-01-09T01:32:46.913 に答える