大VLA溢出

Dav*_*eri 3 c stack-overflow variable-length-array

根据另一个帖子中某人的评论:

VLA引入了比它们解决的问题更多的问题,因为您永远不知道声明是否会因为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;
}
Run Code Online (Sandbox Code Playgroud)

但是这个不能因为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;
}
Run Code Online (Sandbox Code Playgroud)

我的假设是否正确?

我们可以根据对象确定是否使用VLA是危险的(可能会溢出)sizeof吗?

chu*_*ica 5

int (*a)[n];不是VLA,而是指向VLA的指针.所以OP 2的例子并不是足够接近的比较.


正如@MM评论的那样,防止堆栈溢出是任何自动分配的问题.递归可以过度消耗堆栈.本地大变量也可能过度消耗堆栈.

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?
Run Code Online (Sandbox Code Playgroud)

VLA引入了比它们解决的问题更多的问题,因为您永远不知道声明是否会因为x对于堆栈来说太大而崩溃.

我们可以确定使用VLA是否危险吗?

使用正确的工具完成任务. 通常情况下,最坏情况的小型固定大小的阵列会这样做.VLA的用途有限.强大的代码可以确保在声明VLA之前数组元素计数并不愚蠢.

请注意,自C99起可用的VLA在C11中可选.

VLA也不错,他们就是这样画的.