下面的简单 C 程序输出 42
令我惊讶。我预计它会输出垃圾值或 0
,因为堆栈帧对于 foo()
和 bar()
是不同的。输出如何确定为 42
?
#include <stdio.h>
void foo(void){
int a;
printf("%d\n",a);
}
void bar(){
int a=42;
}
int main(){
bar();
foo();
return 0;
}
>>gcc -o test test.c
>>./test
42
当我指示编译器优化代码时,它打印出垃圾!
>>gcc -O -o test test.c
>>./test
2487239847
最佳答案
是的,值 42 是垃圾。这是对它的解释:
堆栈中的每个函数,都以类似的顺序开始
- 函数的参数
- 函数的返回值
- EBP(存储前一帧指针)
- 异常处理框架
- 局部变量
- 缓冲区
- 被叫保存寄存器
在上面的例子中,main()
被调用并遵循上面的过程。
然后遇到bar()
按照1,2,3,4步骤将局部变量a=42
存入内存(5)然后后面跟着6,7那么它就会从内存中出来。
然后它遇到 foo()
遵循与 bar()
具有的内存位置相同的 1、2、3、4 步。并且您声明了一个名为 a
的局部变量,它将指向与保存局部变量 a=42
的 bar()
相同的内存位置。所以它在打印时给出了相同的值 42,这实际上是一个垃圾值。
要验证这一点,试试这个例子:这会打印 7
#include <stdio.h>
#include <string.h>
void foo() {
int b;
printf("%d\n",b);
}
void zoo() {
int dummy = 7;
}
void bar(){
int a1=3;
}
int main(){
bar();
zoo();
foo();
return 0;
}
引用:Doc
关于调用堆栈在 2 个函数调用之间重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42498427/