【发布时间】:2015-06-15 11:52:48
【问题描述】:
考虑以下程序。它从命令行获取一个参数,然后将递归函数展开到该限制。
#include <stdio.h>
#include <stdlib.h>
int rec(int x, int limit) {
if (x == limit) {
return limit;
}
int r = rec(x + 1, limit);
return r - 1;
}
int main(int arc, char* argv[]) {
int result, limit;
limit = atoi(argv[1]);
printf("stack: %p\n", &result);
result = rec(0, limit);
printf("%d\n", result);
}
如果我编译它,我希望它会在固定输入参数限制下用完堆栈。其他事情发生了。
dejan@raven:~/test/stack$ gcc stack.c
dejan@raven:~/test/stack$ ./a.out 174580
stack: 0x7fff42fd58f0
Segmentation fault (core dumped)
dejan@raven:~/test/stack$ ./a.out 174580
stack: 0x7ffdd2dd8b20
0
在两次不同的运行中,堆栈大小似乎不同。这似乎不是编译器问题,因为同样的事情发生在 clang 中,并且反汇编不涉及任何奇怪的事情。
为什么不同运行的堆栈大小不同?
【问题讨论】:
-
@Barmar 我不关心堆栈的位置,只关心大小。随机化将如何影响堆栈的大小?
-
我来这里是和@Barmar 说的一样;但是,我什至不确定程序中声明的第一个变量的地址是否与堆栈位置有很大关系;您的编译器甚至可能不会为该变量分配它自己的空间,而只是将
%EAX中的结果直接传递给printf。 -
@user2357112 在他的程序中没有什么是不确定的,它应该表现一致。它不依赖于系统的任何其他状态。
-
@MarcusMüller 是的,但它应该每次都通过相同的
%EAX。