13

重複の可能性:
Malloc または通常の配列定義?

C と動的変数には動的メモリがあることがわかります。

#include <stdio.h>
int a = 17;
int main(void)
{
  int b = 18; //automatic stack memory
  int * c;
  c = malloc( sizeof( int ) ); //dynamic heap memory
  *c = 19;
  printf("a = %d at address %x\n", a, &a);
  printf("b = %d at address %x\n", b, &b);
  printf("c = %d at address %x\n", *c, c);
  free(c);  
  system("PAUSE");  
  return 0;
}

使用するメモリの種類を知るにはどうすればよいですか? いつどちらか一方をネッドするのですか?

4

6 に答える 6

34

次の状況では動的を使用します。

  1. 大量のメモリが必要な場合。通常のスタック サイズは 1 MB であるため、50 ~ 100 KB を超えるものは動的に割り当てる必要があります。そうしないと、クラッシュの危険があります。一部のプラットフォームでは、この制限をさらに低くすることができます。

  2. 関数が戻った後、メモリが存続する必要がある場合。関数が終了するとスタックメモリが破棄され、必要に応じて動的メモリが解放されます。

  3. サイズが不明な (つまり、大きくなる可能性がある) 構造 (配列やグラフなど) を構築している場合、動的に変化するか、事前計算が難しすぎます。動的割り当てを使用すると、コードは、必要なときにのみ、いつでもメモリを 1 つずつ自然に要求できます。ループ内でより多くのスタック領域を繰り返し要求することはできませんfor

それ以外の場合は、スタック割り当てを優先します。より速く、漏れることはありません。

于 2012-08-28T14:50:51.220 に答える
5

実行時にのみ割り当てのサイズが事前にわからない場合は、ダイナミックメモリを使用します。

たとえば、ユーザーに名前(最大10個の名前など)を入力して文字列配列に格納するように依頼します。ユーザーが提供する名前の数がわからないため(実行時のみ)、割り当て量がわかった後でのみ配列を割り当てる必要があります。これにより、動的割り当てを使用します。

もちろん、固定サイズの10の配列を使用することもできますが、大量の場合、これは無駄になります。

于 2012-08-28T14:44:13.080 に答える
3

プログラムがコンパイル時に割り当てる必要のあるメモリの量が正確にわからない場合は、動的メモリ割り当てを使用してください。

int a[n]たとえば、配列サイズをnに制限します。また、使用するかどうかに関係なく、nx4バイトのメモリが割り当てられました。これはスタックに割り当てられ、変数nはコンパイル時に認識されている必要があります。

int *a = (int *)malloc(n * sizeof (int))一方、実行時に割り当てられ、ヒープ上で割り当てられ、実行時にnのみ認識される必要があり、必ずしもコンパイル時に認識される必要はありません。

これにより、実際に必要なだけのメモリを割り当てることができます。ただし、実行時に割り当てたため、クリーンアップはを使用して実行する必要がありますfree

于 2012-08-28T14:44:45.130 に答える
3

次の場合は、動的メモリを使用する必要があります。

  • オブジェクトが作成されたスコープを超えてオブジェクトを存続させたい場合。
  • 通常、スタック サイズは制限されているため、オブジェクトが多くのメモリを占有している場合、スタック スペースが不足する可能性があります。このような場合、通常は動的メモリ割り当てが行われます。

c99 標準では C に可変長配列 (VLA)が導入されているため、事前に配列の次元がわからないという理由だけで動的メモリ割り当てを使用する必要はありません (もちろん#2上記の場合を除きます)。

言語によって提供される自動メカニズムではなく、明示的にメモリを管理することを意味するため、動的メモリ割り当てをできる限り回避することをお勧めします。 動的メモリ割り当ては常に回避できるわけではなく、使用が不可欠な場合に使用する必要があると述べました (上記の 2 つのケース)。

于 2012-08-28T14:46:51.093 に答える
2

動的割り当てなしでプログラムできる場合は、使用しないでください。
しかし、ある日ブロックされ、ブロックを解除する唯一の方法は動的割り当てを使用することであり、今はそれを使用できます

于 2012-08-28T14:50:14.953 に答える
1

Als は、オブジェクトが作成されたスコープを超えて永続化する必要がある場合は、ヒープからメモリを割り当てる必要があるという興味深い指摘をしました。上記のコードでは、ヒープからメモリを割り当てる必要はまったくありません。次のように書き換えることができます。

#include <stdio.h>
int a = 17;
int main(void)
{
    int b = 18; //automatic stack memory
    int c[1]; // allocating stack memory. sizeof(int) * 1
    c[0] = 19;
    printf("a = %d at address %x\n", a, &a);
    printf("b = %d at address %x\n", b, &b);
    printf("c = %d at address %x\n", c[0], c);
    system("PAUSE");  
    return 0;
}

実際、C99 標準 (可変長配列) の一部として、通常の配列の作成と同じように、演算子を使用[]してスタック上の配列に動的領域を割り当てることができます。コンパイル時に配列のサイズを知る必要さえありません。x86コンパイラは、要求された割り当てスペースに基づいて(マシンの) esp レジスタを調整するだけで、準備完了です。

于 2012-08-28T15:00:22.663 に答える