この「古い」質問に対する興味深い回答がたくさんあり、比較的新しい回答もいくつかありますが、これについて言及しているものは見つかりませんでした。
適切に注意して使用すると、alloca()
(おそらくアプリケーション全体で)小さな可変長割り当て(またはC99 VLAが利用可能な場合)を処理するために一貫して使用すると、固定長の特大ローカル配列を使用する同等の実装よりも全体的なスタックの成長が低下する可能性があります。だから、alloca()
かもしれあなたのスタックのための良いあなたは慎重にそれを使用する場合。
私はその引用を見つけました... OK、私はその引用を作りました。しかし、本当に、それについて考えてください...
@j_random_hackerは非常に右の他の回答の下で彼のコメントである:の使用回避alloca()
コンパイラが関数のインライン化を可能にするために、古い十分でない限り、特大のローカル配列の賛成では(スタックオーバーフローからあなたのプログラムが安全なことはありません使用することalloca()
で、その場合、あなたがしなければなりませんアップグレードするか、alloca()
ループ内で使用しない限り、ループ内で使用しないでくださいalloca()
)。
デスクトップ/サーバー環境と組み込みシステムに取り組んできました。多くの組み込みシステムはヒープをまったく使用しません(それらをサポートするためにリンクすることもありません)。これは、動的に割り当てられたメモリは、決してアプリケーションのメモリリークのリスクにより悪であるという認識を含むためです。一度に何年も再起動することもあれば、動的メモリが危険であるという正当な理由がある場合もあります。これは、アプリケーションがヒープを断片化して、誤ってメモリを使い尽くすことはないためです。そのため、組み込みプログラマーにはいくつかの選択肢があります。
alloca()
(またはVLA)は、ジョブに最適なツールです。
プログラマーがスタックに割り当てられたバッファーを「可能なあらゆるケースを処理するのに十分な大きさ」にするところを何度も何度も見ました。深くネストされた呼び出しツリーでは、その(アンチ?)パターンを繰り返し使用すると、スタックの使用が誇張されます。(20レベルの呼び出しツリーを想像してください。さまざまな理由で各レベルで、関数は通常1024バイトのバッファーを「安全のために」盲目的に過剰に割り当てますが、通常は16バイト以下しか使用せず、非常にまれにそれ以上使用する場合があります。)alloca()
またはVLAを使用して、関数が必要とするだけのスタックスペースのみを割り当て、スタックへの不必要な負荷を回避します。うまくいけば、呼び出しツリー内の1つの関数が通常よりも大きい割り当てを必要とする場合でも、呼び出しツリー内の他の関数は通常の小さい割り当てを使用しており、アプリケーションスタック全体の使用量は、すべての関数がローカルバッファを盲目的に割り当てすぎた場合よりも大幅に少なくなります。
しかし、使用することを選択した場合alloca()
...
このページの他の回答に基づいて、VLAは安全であるようです(ループ内から呼び出された場合はスタック割り当てを複合しません)。ただし、alloca()
を使用している場合は、ループ内で使用しないように注意し、別の関数のループ内で呼び出される可能性がある場合は、関数をインライン化できないようにしてください。