7

次の C コードを検討してください。

    #include <stdio.h>
    #include <stdlib.h>

    int main() {

        int arrSize;
        scanf("%d", &arrSize);
        printf("%d\n",arrSize);

        int *dynArr = (int *)malloc(sizeof(int)*arrSize);
        int arr1[arrSize];

        return 0;
    }

上記のコードでは、arrSizeはユーザー入力から取得した配列のサイズです。次の観察が正しいかどうかを知りたいです。

  • dynArrは、実行時にヒープでメモリに割り当てられる動的配列です。dynArr のサイズは、realloc関数を使用して変更できます。

  • arr1も実行時にメモリに割り当てられますが、動的ではなく (つまり、サイズを変更できません)、Stackに割り当てられます。

4

4 に答える 4

4

dynArr実行時にヒープ セクションからメモリが割り当てられる動的配列です。関数を使用してサイズをdynArr変更できますrealloc

  • いいえ、によって返されたポインターを使用して初期化されるdynArrポインターですmalloc()。配列はポインターではなく、その逆も同様です。場合によっては、配列名が配列の最初の要素へのポインターに減衰しますが、両方が同じになるわけではありません。

  • size ofdynArrはポインタのサイズであり、ポインタが指すメモリ位置のサイズではありません。正しい単語を使用すると、 は次のように表すことができます。それが指すメモリのサイズは、を使用して変更できますrealloc()

arr1実行時にもメモリが割り当てられますが、動的ではありません。つまり、サイズを変更することはできません。メモリは、スタックまたはデータ セクションから割り当てられます。(どのセクション ヒープまたはスタック/データからメモリが割り当てられているのか、またその理由がわからない)。

これを可変長配列と呼びます。他の点は正しいです。

引用C11、章§6.7.6.2

size が整数定数式ではない式の場合: 関数プロトタイプ スコープでの宣言内にある場合は、* に置き換えられたものとして扱われます。それ以外の場合は、評価されるたびにゼロより大きい値になります。可変長配列型の各インスタンスのサイズは、その存続期間中は変更されません。

于 2017-01-02T07:57:35.160 に答える
2

空きメモリ ストアからメモリを割り当てます。Cの場合、メモリにはヒープとスタックと呼ばれるものはありません..それは論理的に考えるものですC.(Cの実装では)]


宣言されている範囲が終わっても生きていたいものが必要かどうか、私たちが気にするのはそれだけです。

ヒープの場合はそうです..スタックの場合はそうではありません。

あなたの場合

int arr1[arrSize];このメイン関数のローカル変数が格納されているのと同じフレームに割り当てられます。

ダイナミック アロケーション

これらのメモリ ロケーションの正確なサイズと寿命を制御します。それを解放しないと、メモリ リークが発生し、アプリケーションがクラッシュする可能性があります。( dynArr)

実際...

ヒープ

ヒープは、自動的に管理されないコンピューターのメモリ領域であり、CPU によって厳密に管理されていません。これは、メモリのより自由に浮動する領域です (そしてより大きくなります)。ヒープにメモリを割り当てるには、C の組み込み関数である malloc() または calloc() を使用する必要があります。

ヒープにメモリを割り当てたら、必要がなくなったら free() を使用してそのメモリの割り当てを解除する必要があります。これを行わないと、プログラムでメモリ リークと呼ばれるものが発生します。つまり、ヒープ上のメモリは引き続き確保されます (他のプロセスでは使用できません)。

スタック

これは、各関数 (main() 関数を含む) によって作成された一時変数を格納するコンピューターのメモリの特別な領域です。スタックは "LIFO" (後入れ先出し) データ構造であり、CPU によって非常に厳密に管理および最適化されます。関数が新しい変数を宣言するたびに、スタックに「プッシュ」されます。その後、関数が終了するたびに、その関数によってスタックにプッシュされたすべての変数が解放されます (つまり、削除されます)。スタック変数が解放されると、そのメモリ領域は他のスタック変数に使用できるようになります。

資力

于 2017-01-02T07:55:22.240 に答える
1

実際、可変長配列は Google C++ スタイル ガイドでは許可されていません。自然に見える構文を持ち、効率的ですが、データに依存する量のスタック スペースを割り当てるため、深刻で不可解なメモリ上書きバグを引き起こす可能性があります。

「自分のマシンでは問題なく動作したが、本番環境で不思議なことに死ぬ」ことが時々ありました。

于 2017-01-02T08:24:11.197 に答える