0

ここで Noob と私は 2 つの質問があります。

1) この int a[10] のような配列を作成する場合、システムは配列のメモリをどのようにセットアップしますか? つまり、システムは 10 個の 1 ワード メモリを連続して (ヒープで) 割り当てますか? char a[10] はどうですか?またはユーザー定義型?

2) ダイナミック アロケーションはどうですか? int *a = new int[10]; など この配列はメモリ内でどのように設定されていますか? (質問 1 と同様の質問)。

4

2 に答える 2

4

この動作は C++ 標準では保証されていません。スタックやヒープについても言及されていません。

ただし、通常、関数を呼び出すと、その関数のすべての自動変数 (および戻り値などの他のオブジェクト) を格納するのに十分な大きさのスタックにスタック フレームがプッシュされます。したがって、関数を考えるとfoo

void foo() {
  int x;
  std::string str;
}

この関数が呼び出されると、スタックの一番上が押し上げられ、intと のための十分なスペースが確保されstd::stringます。これらの型のサイズは実装で定義されており、標準によっていくつかの制限が課されていますがsizeof(int)sizeof(std::string)バイトと考えることができます。

関数に などの配列がある場合、関数int a[10]のスタック フレームには 10int秒または10*sizeof(int)バイトに十分なスペースが含まれます。このフレーム サイズは実行可能ファイルに組み込まれます。関数が呼び出されると、スタックはそのサイズだけ増加します。

などの動的割り当てを行う場合、ヒープ内int* a = new int[10]に 10int秒または のスペースを割り当てます。10*sizeof(int)ただし、スタック フレームをある程度増やしましたsizeof(int*)。ポインター オブジェクト自体はスタックに格納されますが、intそれが指す s はヒープ上にあります。

std::string最初の例では、が可変長である場合、スタック フレームのサイズを実行可能ファイルにどのように組み込むことができるか疑問に思うかもしれません。これは、std::stringオブジェクト自体のサイズが固定されているためですsizeof(std::string)が、内部表現を管理するためにある種の動的割り当てを行う可能性が最も高いためです。この内部表現はヒープ上にあります。

于 2012-12-01T21:33:50.850 に答える
1
  1. スタック上にバイト ストレージ ブロックが取得されるため10 * sizeof(type)(オーバーフローが発生しないと仮定)、メモリ内の各要素は連続して同じサイズになります。これが、配列の要素に対するポインター演算が機能する理由です。範囲外になると、このメモリは割り当て解除されます。このメモリは必ずしも初期化されるわけではないことに注意してください。の場合、int[10]0 ではなくジャンクが含まれます。

  2. 同じですが、要素はスタックではなくフリー ストアにあります。newメモリを割り当てられない場合は例外をスローします。new[]オーバーロードすることもできます。が呼び出されると、このメモリの割り当てが解除されます。そのため、ベクターがスコープ外になったときにメモリの割り当てを解除し、使用の他の側面をより簡単にするため、通常は次のdelete[]ような方が適しています。std::vector

于 2012-12-01T21:30:35.160 に答える