10

時代遅れで使用すべきではないかなりの数の場所を読みましたが、alloca代わりに可変長配列を使用する必要があります。

私の質問はこれです:alloca可変長配列で完全に置き換え可能ですか?

私の特定の例では、次のようなものがあります。

typedef struct { 
  int *value; 
  size_t size; 
  } some_type;

void SomeExternalFunction(some_type);

...

void foo(){
  //What I thought to do
  some_type bar;
  bar.value=alloca(sizeof(int)*10);
  SomeExternalFunction(bar);

  //what should be done without alloca
  some_type fizz;
  int tmp[10];
  fizz.value=tmp;
  SoemExternalFunction(fizz);
}

私は何かを見逃していますか、それともこれは alloca の実際の有効な使い方ですか? また、この例では、何らかの理由で値をスタックに割り当てたいと仮定します

4

2 に答える 2

24

VLA と alloca の間には重要な違いがあります。 alloca() が返すメモリは、現在の関数が持続する限り有効です。VLA が占有するメモリの有効期間は、VLA の識別子がスコープ内にある限り有効です。たとえば、ループ内で alloca() メモリを使用し、ループの外側でメモリを使用できます。ループが終了すると識別子が範囲外になるため、VLA はなくなります。これは、alloca() と十分なスタック スペースを使用してこれを実行できることを意味します。

typedef struct node { int data; struct node *next; };
void fun()
{
 struct node *n=0;
 int d;
 /* Now we are building a single-linked list on the stack! */
 while(d=get_something()) {
  struct node *x=alloca(sizeof(*x));
  x->next=n; 
  x->data=d;
  n=x;
 }
 do_something_with(n);
} // and the whole thing is deleted here..

VLA でこれを行うことはできません。

于 2010-08-15T19:36:23.770 に答える
-3

allocamallocとで完全に置き換え可能freeです。もう少し手間がかかりますが、よほど注意しない限り、必須です。または C99 vlaを使用するほぼすべてのコードallocaは、スタック オーバーフロー攻撃に対して脆弱であり、多くの実装では、特権の昇格につながる可能性があります。スタックの大きさや残りのスタックスペースの量 (または、コンパイラの内部使用やさらなる関数呼び出しのために、要求されたサイズを超えるオーバーヘッドがどれだけ必要になるか) を知るための移植可能な方法はないため、そのためにできる唯一の合理的な方法は、 make vla's/ allocasafe は、サポートするデータのサイズに非常に小さい人為的な制限を課します (たとえば、数 kb)。この時点で、単純な非可変長自動オブジェクトを使用することもできます...

于 2010-08-16T05:41:57.030 に答える