从输入参数声明自动变量的数组大小

时间:2009-09-25 00:41:27

标签: c stack

我一直在运行gcc 4.3.3的Ubuntu 9.04系统上使用堆栈,其中randomize_va_space内核变量设置为0(/ proc / sys / kernel / randomize_va_space)

如果我在函数中声明一个auto变量,该函数是一个大小由输入决定的数组,那么如何在堆栈上分配数组?

该功能看起来像这样 -

int fun(int i) {
    char a[i];
    char *ptr;

    printf("a - %p ptr - %p\n", a, &ptr);
    printf("Difference - %ld\n", ((unsigned long)&ptr - (unsigned long)a);
    printf("sizeof(a) - %d\n\n", sizeof(a));
}

当传递数组a时,sizeof运算符返回预期的大小(甚至-1),所以我想知道为什么数组在堆栈上占用了这么多空间,其次为什么sizeof()返回-1?

输出看起来像这样 -

a - 0xbffff4c0 ptr - 0xbffff4fc
Difference - 60
sizeof(a) - -1

a - 0xbffff4c0 ptr - 0xbffff4fc
Difference - 60
sizeof(a) - 0

a - 0xbffff4c0 ptr - 0xbffff4fc
Difference - 60
sizeof(a) - 1

a - 0xbffff4b0 ptr - 0xbffff4fc
Difference - 76
sizeof(a) - 2

a - 0xbffff4b0 ptr - 0xbffff4fc
Difference - 76
sizeof(a) - 3

a - 0xbffff4b0 ptr - 0xbffff4fc
Difference - 76
sizeof(a) - 4

3 个答案:

答案 0 :(得分:5)

C99中引入了可变长度自动数组。

通过数组大小调整堆栈指针来分配数组,就像普通的自动变量一样 - 唯一的区别是堆栈指针调整的大小和a与帧指针的偏移量是不是可以在编译时计算的常量 - 它们必须在运行时计算。

类似地,为了使sizeof能够在可变长度数组上正常工作,当它应用于这样的数组时,它也无法在编译时计算。输入范围时,必须记住分配的a大小。

这是内务处理信息 - 可变长度自动数组的数量,大小和偏移量 - 在aptr之间的额外空间中保留在堆栈中。那里可能还有一个额外保存的帧指针 - 你真的必须深入挖掘源代码才能找到你的编译器。

哦,你从-1看到sizeof的原因是因为你使用%d说明符错误地打印了它 - 使用%zu表示size_t }}

答案 1 :(得分:1)

支持C99变量数组语义的编译器应该编译它(虽然我对var数组没有多少经验)。

每次迭代都传递i的值是多少?这有助于解释为什么aizeof()在某些情况下会返回-1

根据这个页面:

可变长度数组在主线GCC中工作,但根据:

他们在GCC 4.3中被打破了。这可能解释了您在使用sizeof()时遇到的问题。

答案 2 :(得分:0)

我很惊讶这个编译。编译器无法在编译时在堆栈上分配内存,除非它知道要分配多少内存。使用'new'或'malloc'进行分配时,内存将从堆中分配。这是我编译时得到的结果:

alloc.c(2):错误C2057:预期的常量表达式
alloc.c(2):错误C2466:不能分配一个常量大小为0的数组 alloc.c(2):错误C2133:'a':未知大小
alloc.c(7):警告C4034:sizeof返回0

我认为问题的其余部分没有实际意义。

相关问题