違いは何ですか
void *bytes = alloca(size);
と
char bytes[size]; //Or to be more precise, char x[size]; void *bytes = x;
...ここで、サイズはコンパイル時に値が不明な変数です。
違いは何ですか
void *bytes = alloca(size);
と
char bytes[size]; //Or to be more precise, char x[size]; void *bytes = x;
...ここで、サイズはコンパイル時に値が不明な変数です。
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 コンパイラが必要です。
GNUドキュメントから:
alloca で割り当てられたスペースは、それを含む関数が戻るまで存在します。可変長配列のスペースは、配列名のスコープが終了するとすぐに解放されます。(同じ関数で可変長配列と alloca の両方を使用する場合、可変長配列の割り当てを解除すると、alloca で最近割り当てられたものもすべて割り当て解除されます。)
また、alloca
は標準の C 関数ではないため、すべてのコンパイラでのサポートが保証されているわけではありません。可変長配列は C99 標準の一部であるため、C99 をサポートするコンパイラはそれを実装する必要があります。
ビリーが言及した点に加えて、alloca
非標準です(C99にもありません)。
最大の違いは、メモリをクラス変数として使用している場合、allocaはコンストラクタまたはデストラクタを呼び出さないことです。
他の違いは気付かれにくいですが、状況によっては奇妙な実行時エラーで明らかになる可能性があります。
正確にスペースがいつ解放されるか、および構成がまったくサポートされているかどうかについての既に説明したポイントに加えて、これもあります。
alloca
場合、bytes
ポインター型を持ちます。[]
場合、bytes
配列型を持ちます。最も顕著な違いは、何であるかsizeof(bytes)
です。ポインターの場合はポインターのサイズ ( sizeof(void *)
) ですが、配列の場合は割り当てられたスペースのサイズ ( sizeof(char) * size
、size
この場合はsizeof(char)
= 1 であるため = ) です。
(また、あなたの例では、要素の型が異なります。同じにするためには、最初のものを に変更する必要があります char *bytes = alloca(size)
。)
2 番目の形式でsize
は、コンパイル時に既知の定数でなければなりません。