大 VLA 溢出
Large VLA overflow
基于另一个线程中某人的评论:
VLAs introduce more problems than they solve, because you never know
if the declaration is going to crash for x being too large for the
stack.
此代码将溢出,因为 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 是否危险(可能溢出)?
int (*a)[n];
不是 VLA,而是指向 VLA 的指针。所以 OP 2 的例子不是一个足够接近的比较。
正如 评论的那样,防止堆栈溢出是任何自动分配的问题。递归会过度消耗堆栈。局部大变量也会过度消耗堆栈。
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?
VLAs introduce more problems than they solve, because you never know if the declaration is going to crash for x being too large for the stack.
Can we determine if the use of a VLA is dangerous?
使用正确的工具完成任务。 通常 worst-case 小的 fixed-sized 数组就可以了。 VLA 的用途有限。在声明 VLA 之前,健壮的代码将确保数组元素计数不是愚蠢的。
请注意,VLA 可用,因为 C11 可选择支持 C99。
VLA 还不错,他们是 just drawn that way。
基于另一个线程中某人的评论:
VLAs introduce more problems than they solve, because you never know if the declaration is going to crash for x being too large for the stack.
此代码将溢出,因为 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 是否危险(可能溢出)?
int (*a)[n];
不是 VLA,而是指向 VLA 的指针。所以 OP 2 的例子不是一个足够接近的比较。
正如
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?
VLAs introduce more problems than they solve, because you never know if the declaration is going to crash for x being too large for the stack.
Can we determine if the use of a VLA is dangerous?
使用正确的工具完成任务。 通常 worst-case 小的 fixed-sized 数组就可以了。 VLA 的用途有限。在声明 VLA 之前,健壮的代码将确保数组元素计数不是愚蠢的。
请注意,VLA 可用,因为 C11 可选择支持 C99。
VLA 还不错,他们是 just drawn that way。