您可以通过不使用它们来防止它们崩溃。:)
严肃地说,几乎没有安全的方法可以使用可变长度数组来让你的生活更轻松,除非你对大小有很强的限制。另一方面,您可以通过以下方式有条件地使用它们:
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 可能有用的另一个模糊情况是在递归算法中,您知道所有递归级别所需的数组条目总数为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;
}