我试图弄清楚地址如何分配给堆栈上的变量.我运行下面的小程序:
int main() { long a; int b; int c; printf("&a = %p\n", &a); printf("&b = %p\n", &b); printf("&c = %p\n", &c); }
我预期的输出是(考虑到地址正在下降):
&a = 0x7fff6e1acb88 &b = 0x7fff6e1acb80 &c = 0x7fff6e1acb7c
但相反,我得到了:
&a = 0x7fff6e1acb88 &b = 0x7fff6e1acb80 &c = 0x7fff6e1acb84
为什么c
变量位于a
和b
变量之间?变量是否在声明时未放入堆栈?
我试着更换的类型a
,从long
到int
,我得到这个:
&a = 0x7fff48466a74 &b = 0x7fff48466a78 &c = 0x7fff48466a7c
在这里,我不明白为什么地址会上升,而它们之前会下降?
我使用了编译程序gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-11precise2)
,如果有任何帮助的话.
变量是否在声明时未放入堆栈?
没有.
为什么地址会上升,而它们之前会下降?
他们可能会上升,但他们没有必要.
编译器可以自由地重置它认为合适的局部变量的顺序,或者它甚至可以删除或添加一些变量.
即使堆栈指针在给定CPU上向下计数,程序也将使用堆栈帧.如何在堆栈帧内分配某个参数是实现定义的.
另请注意,某些CPU具有向上计数堆栈指针.
另请注意,局部变量不一定在堆栈上分配.更常见的是,它们被分配在CPU寄存器中.但是当你获取变量的地址时,你会强制编译器在堆栈上分配它,因为寄存器没有地址.
变量不一定按照声明的顺序放在堆栈上.你无法预知那里堆栈,他们将是-他们可以在任何顺序.正如glglgl在评论中指出的那样,它们甚至不必存在于堆栈中,而且可以简单地保存在寄存器中.