对于以下代码
#include <stdio.h>
void f() {
int x;
printf("x = %d\n", x);
}
void g() {
int y = 42;
printf("y = %d\n", y);
}
int main() {
f();
g();
return 0;
}
我得到以下输出
x = 22031
y = 42
如果我更改在main()
中执行的最后两个函数的顺序并运行代码
void f() {
int x;
printf("x = %d\n", x);
}
void g() {
int y = 42;
printf("y = %d\n", y);
}
int main() {
g();
f();
return 0;
}
我得到以下信息:
y = 42
x = 42
有人可以向我解释这一点吗。我知道这与在地址中分配内存有关,但是我不确定细节。
答案 0 :(得分:0)
您从“其他”(即undefined behavior)中看到内存中的未初始化值。当您运行程序时,您会发现并看到内存中的“旧”值来自计算机中程序以外的其他内容。
例如,以下程序将遇到未定义的行为,因为x
在初始化之前已被读取,并且x的值来自另一个进程:
#include <stdio.h>
int main() {
int x;
printf("x = %d\n", x);
return 0;
}
答案 1 :(得分:0)
x = 22031
y = 42
X值是未初始化的堆栈垃圾值。当您的程序加载到RAM中时,它不会将堆栈或堆内存清零。这是C programs memory model的参考。
有趣的情况是
y = 42
x = 42
那么这是怎么回事?好吧,当您首先调用g函数时,会将值弹出到堆栈上(在内存模型中向下增大,或者在内存模型不同的情况下向上增大)。下次调用f函数时,未初始化的堆栈垃圾的值已更改为调用g时分配的值(将y的地址分配为42)。这是因为在两个函数中,具有相同数量的参数和局部变量被压入堆栈,如果进行调整,将会看到不同的值。例如,以下g定义可能会导致x打印43,具体取决于如何将局部变量弹出到堆栈上。
void g() {
volatile int z = 43;
int y = 42;
printf("y = %d\n", y);
}
如果您想弄乱它,则使编译器不会将其优化为“ z”。