可変長配列(VLA)はC99標準で登場し、それ以前は配列のすべてのサイズをコンパイル時に知っている必要がありました。実行時にのみ知られている変数によってサイズが決定される配列を宣言することができます。
VLAの誤った使用は、メモリ割り当てエラー(たとえば、配列のサイズが大きすぎるとスタックオーバーフローになる)を引き起こし、異なるコンパイラ間でVLAを渡すことができなくなり(すべてのコンパイラがそれをサポートしているわけではない)、古いCおよびC++標準との互換性が制限されます。また、メモリはスタックに割り当てられるため、デバッグが難しくなることがあります。
VLAを使用する際は、スタック上に存在し、グローバルまたは静的にできないことを考慮する必要があります。C++との相互運用性や柔軟性が必要な場合は、mallocを介した動的配列を選択するのが良いです。VLAのサポートが保証されていない場合は、静的配列やC90標準に制限することをお勧めします。
コードの例:
#include <stdio.h> void process(size_t n) { int arr[n]; // VLA for(size_t i = 0; i < n; i++) arr[i] = i; for(size_t i = 0; i < n; i++) printf("%d ", arr[i]); } int main() { process(5); return 0; }
主な特徴:
関数内で可変長の静的配列をstatic int arr[n];として宣言することはできますか?
いいえ、静的変数はコンパイル時に特定のサイズを持つ必要があります。したがって、static int arr[n];という可変サイズはコンパイルエラーを引き起こします。
関数から出るときにVLAは自動的に解放されますか?
はい、VLAはスタック上に配置されており、ブロック/関数から出ると自動的にメモリが解放されます。通常のローカル変数と同じです。
非常に大きなサイズのVLAを安全に割り当てることはできますか?
いいえ、スタックのサイズには制限があります(たとえば、1MBまたは8MB)。大きなVLAを割り当てようとすると、実行時エラー(スタックオーバーフロー)が発生します。
VLAを使用したクロスプラットフォームコードを作成しましたが、古いまたは厳しく設定されたコンパイラではコンパイルできませんでした。
利点:
欠点:
VLAをローカルなタスクと小さいサイズが保証される場所でのみ使用し、大きな配列にはmalloc/freeを使用しました。
利点:
欠点: