在C中执行堆栈

时间:2018-11-12 23:25:22

标签: c memory stack

对于以下代码

#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

有人可以向我解释这一点吗。我知道这与在地址中分配内存有关,但是我不确定细节。

2 个答案:

答案 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”。