使用しないことでクラッシュを防ぐことができます。:)
真面目な話ですが、サイズに強い制限がない限り、可変長配列を使用して作業を楽にする安全な方法はほとんどありません。一方、次のように条件付きで使用できます。
char vla_buf[n < 1000 ? n : 1];
char *buf = sizeof vla_buf < n ? malloc(n) : vla_buf;
if (!buf) goto error;
/* ... Do stuff with buf ... */
if (buf != vla_buf) free(buf);
これは役に立たない苦痛のように見えますが、特に多くの呼び出しが行われ、ロックの競合が発生する可能性があるスレッド化されたアプリケーションでは、パフォーマンスに大きな違いmalloc
がfree
生じる可能性があります。(このトリックの注目すべき副次的な利点は、マクロなどに置き換えるだけ[n < 1000 ? n : 1]
で1000
、VLAなしで古いコンパイラをサポートできることです。)
VLAが役立つ可能性のあるもう1つのあいまいなケースは、再帰アルゴリズムの場合です。再帰アルゴリズムでは、再帰のすべてのレベルで必要な配列エントリの総数がによって制限されます。n
ここでn
は、スタックがオーバーフローしないと確信できるほど小さいですが、最大の再帰レベルと、最大の要素n
を使用する個々のレベルである可能性があります。n
C99より前は、n^2
スタックスペースを使用せずにこのケースを処理する唯一の方法は、を使用することでしたmalloc
。VLAを使用すると、スタック上で問題を完全に解決できます。
VLAが本当に有益であるこれらのケースは、非常にまれであることに注意してください。通常、VLAは、作成した(悪用するのが簡単な)脆弱性に気付くまで、メモリ管理が簡単であると自分自身を欺く方法にすぎません。:-)
編集: OPの元の質問によりよく対処するには:
#define MAX_VLA 10000
int bar(size_t n)
{
int arr[n <= MAX_VLA ? n : 1];
if (sizeof arr/sizeof *arr < n) return ENOMEM;
/* ... */
return 0;
}