web-dev-qa-db-ja.com

スタックまたはヒープでのC ++のグローバルメモリ管理

C++アプリケーションでデータ構造をグローバルに宣言する場合、スタックメモリまたはヒープメモリを消費しますか?

例えば

struct AAA
{

.../.../.
../../..
}arr[59652323];
69

私は答えに満足していなかったので、同じkarjatkarが単純なyes/noの答え以上のものを学びたいと望んでいるので、ここに行きます。

通常、プロセスには5つの異なるメモリ領域が割り当てられています

  1. コード-テキストセグメント
  2. 初期化データ-データセグメント
  3. 未初期化データ-bssセグメント
  4. ヒープ
  5. スタック

どこに保存されているかを本当に知りたい場合は、これらを読んでブックマークしてください:

コンパイラー、アセンブラー、リンカー、ローダー:簡単なストーリー (表w.5を参照)

メモリ内のプログラムの構造

alt text

131
Milan

ここでの問題は質問です。あなたが小さなC(++も同様に、これを同じ方法で処理する)プログラムを持っていると仮定しましょう:

/* my.c */

char * str = "Your dog has fleas.";  /* 1 */
char * buf0 ;                         /* 2 */

int main(){
    char * str2 = "Don't make fun of my dog." ;  /* 3 */
    static char * str3 = str;         /* 4 */
    char * buf1 ;                     /* 5 */
    buf0 = malloc(BUFSIZ);            /* 6 */
    buf1 = malloc(BUFSIZ);            /* 7 */

    return 0;
}
  1. これはスタックNORヒープに割り当てられません。代わりに、静的データとして割り当てられ、最新のマシンの独自のメモリセグメントに配置されます。実際のstring =も静的データとして割り当てられ、正しい考え方のマシンの読み取り専用セグメントに入れられます。
  2. 単に静的に割り当てられたポインターです。静的データ内の1つのアドレスのスペース。
  3. stackにポインターが割り当てられており、mainが戻ったときに効果的に割り当てが解除されます。文字列は定数なので、他の文字列とともに静的データ空間に割り当てられます。
  4. 実際には2とまったく同じように割り当てられます。staticキーワードは、スタックに割り当てられないことを示します。
  5. ...しかしbuf1はスタック上にあり、
  6. ... mallocされたバッファスペースがヒープ上にあります。
  7. ところで、子供は家でこれを試さないでください。 mallocには目的の戻り値があります。 always戻り値を確認する必要があります。

例えば:

char * bfr;
if((bfr = malloc(SIZE)) == NULL){
   /* malloc failed OMG */
   exit(-1);
}
27
Charlie Martin

通常、どちらも消費しません。プログラム実行のために一定サイズのままである可​​能性が高いメモリセグメントにそれらを割り当てようとします。 bss、スタック、ヒープ、またはデータの可能性があります。

14
Tomek Kopczuk

どちらでもない。 .dataセクションです。

6
EFraim

グローバルメモリは、アプリケーションによる割り当て方法に応じて、固定メモリブロックまたはヒープに事前に割り当てられます。

byte x[10]; // pre-allocated by the compiler in some fixed memory block
byte *y

main()
{
   y = malloc(10); // allocated on the heap
}

[〜#〜] edit [〜#〜]

問題は紛らわしいです:C++アプリケーションでデータ構造をグローバルに割り当てる場合、スタックメモリまたはヒープメモリを消費しますか? =

「割り当てる」?これは、malloc()の呼び出しなど、多くのことを意味します。 「データ構造をグローバルに宣言および初期化する場合」という質問であれば、それは異なっていただろう。

何年も前、CPUがまだ64Kセグメントを使用していたとき、一部のコンパイラは、.dataセグメント内のブロックを予約するのではなく、ヒープからメモリを動的に割り当てるのに十分賢いものでした(メモリアーキテクチャの制限のため)。

私は年を取りすぎていると思います...

5

C++でデータ構造をグローバルに宣言することも、ヒープメモリまたはスタックメモリを消費しません。実際、グローバル変数は通常、プログラム全体でサイズが変更されないデータセグメントに割り当てられます。スタックとヒープは通常、プログラムの実行中に作成および破棄される変数に使用されます。

Program Memory Space

2
DML

グローバルオブジェクト自体は、mainが実行される前にランタイムまたはコンパイラが確保するメモリを占有します。これは可変ランタイムコストではないため、スタックもヒープもありません。

オブジェクトのctorがメモリを割り当てる場合、それはヒープ内にあり、オブジェクトによる後続の割り当てはすべてヒープ割り当てになります。

グローバルオブジェクトのポインターまたはオブジェクト自体全体である場合、グローバルオブジェクトの正確な性質に依存します。

0
Rudi Bierach