基于另一个帖子中某人的评论:
VGA引入的问题多于他们解决的问题,因为您永远不会知道 如果声明要崩溃,因为x太大了 叠加。
此代码将溢出,因为sizeof(a)
对于堆栈来说太长了:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n = 100000000;
int a[4][n];
printf("%zu\n", sizeof(a));
return 0;
}
但是这个不能,因为sizeof(a)
是8(我的计算机中指针的大小):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n = 100000000;
int (*a)[n];
printf("%zu\n", sizeof(a));
a = malloc(sizeof(*a) * 4);
free(a);
return 0;
}
我的假设是否正确?
我们可以根据sizeof
对象判断VLA的使用是否危险(可能会溢出)吗?
答案 0 :(得分:5)
int (*a)[n];
不是VLA,而是指向VLA的指针。所以OP 2的例子并不是足够接近的比较。
如@M.M所述,防止堆栈溢出是任何自动分配的问题。递归可以过度消耗堆栈。本地大变量也可能过度消耗堆栈。
VLA只是更可能被使用的一种。
// Qualified use of VLA
int len = snprintf(NULL, 0 "%d", some_int);
assert(len > 0);
char vla_good[len+1];
len = snprintf(vla_good, len+1, "%d", some_int);
// Unqualified
int x;
scanf("%d", &x);
char vla_bad[x]; // who knowns what x may be, did scanf() even work?
VLA引入的问题比他们解决的问题多,因为您永远不知道声明是否会因为x对于堆栈来说太大而崩溃。
我们可以确定使用VLA是否危险吗?
使用正确的工具完成任务。通常最坏情况的小型固定大小的阵列都可以。 VLA的用途有限。强大的代码可以确保在声明VLA之前数组元素计数并不愚蠢。
请注意,自C99起可用的VLA在C11中可选。
VLA也不错,他们是just drawn that way。