我一直在运行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
答案 0 :(得分:5)
C99中引入了可变长度自动数组。
通过数组大小调整堆栈指针来分配数组,就像普通的自动变量一样 - 唯一的区别是堆栈指针调整的大小和a
与帧指针的偏移量是不是可以在编译时计算的常量 - 它们必须在运行时计算。
类似地,为了使sizeof
能够在可变长度数组上正常工作,当它应用于这样的数组时,它也无法在编译时计算。输入范围时,必须记住分配的a
大小。
这是内务处理信息 - 可变长度自动数组的数量,大小和偏移量 - 在a
和ptr
之间的额外空间中保留在堆栈中。那里可能还有一个额外保存的帧指针 - 你真的必须深入挖掘源代码才能找到你的编译器。
哦,你从-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
我认为问题的其余部分没有实际意义。