9

違いは何ですか

void *bytes = alloca(size);

char bytes[size];  //Or to be more precise, char x[size]; void *bytes = x;

...ここで、サイズはコンパイル時に値が不明な変数です。

4

6 に答える 6

17

alloca()現在の関数が終了するまでメモリを再利用しませんが、可変長配列は現在のブロックが終了したときにメモリを再利用します。

別の言い方をすれば:

void foo()
{
    size_t size = 42;
    if (size) {
        void *bytes1 = alloca(size);
        char bytes2[size];
    } // bytes2 is deallocated here
}; //bytes1 is deallocated here

alloca()任意の C89 コンパイラで (ある意味で) サポートできますが、可変長配列には C99 コンパイラが必要です。

于 2010-04-10T19:05:09.640 に答える
6

GNUドキュメントから:

alloca で割り当てられたスペースは、それを含む関数が戻るまで存在します。可変長配列のスペースは、配列名のスコープが終了するとすぐに解放されます。(同じ関数で可変長配列と alloca の両方を使用する場合、可変長配列の割り当てを解除すると、alloca で最近割り当てられたものもすべて割り当て解除されます。)

また、allocaは標準の C 関数ではないため、すべてのコンパイラでのサポートが保証されているわけではありません。可変長配列は C99 標準の一部であるため、C99 をサポートするコンパイラはそれを実装する必要があります。

于 2010-04-10T19:09:55.813 に答える
5

ビリーが言及した点に加えて、alloca非標準です(C99にもありません)。

于 2010-04-10T19:10:07.563 に答える
0

最大の違いは、メモリをクラス変数として使用している場合、allocaはコンストラクタまたはデストラクタを呼び出さないことです。

他の違いは気付かれにくいですが、状況によっては奇妙な実行時エラーで明らかになる可能性があります。

于 2010-04-12T17:07:11.273 に答える
0

正確にスペースがいつ解放されるか、および構成がまったくサポートされているかどうかについての既に説明したポイントに加えて、これもあります。

  • このalloca場合、bytesポインター型を持ちます。
  • この[]場合、bytes配列型を持ちます。

最も顕著な違いは、何であるかsizeof(bytes)です。ポインターの場合はポインターのサイズ ( sizeof(void *)) ですが、配列の場合は割り当てられたスペースのサイズ ( sizeof(char) * sizesizeこの場合はsizeof(char)= 1 であるため = ) です。

(また、あなたの例では、要素の型が異なります。同じにするためには、最初のものを に変更する必要があります char *bytes = alloca(size)。)

于 2010-04-10T19:26:44.787 に答える
0

2 番目の形式でsizeは、コンパイル時に既知の定数でなければなりません。

于 2010-04-10T19:05:12.047 に答える