函数 return 后未释放 C 自动变量

C auto variable isn't freed after function return

我有以下 C 代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct num {
  int a;
  struct num *c;
} num;

void init_struct(num *n) {
  num some_num = { 1 };

  n->c = &some_num;
}

int main() {
  num *n = malloc(sizeof(num));
  init_struct(n);

  printf("%d\n", (n->c)->a);
  return 0;
}

根据我的理解,对 printf("%d\n", (n->c)->a) 的调用应该会导致分段错误,因为它正在访问已经释放的内存。但实际上,它 returns 1.

我的推理如下:

事实并非如此,但我不知道为什么。

我运行这个和gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)

哦,解脱好了。引用 Raymond Chen 的话,“看似工作是未定义的行为,但它仍然是未定义的。”

访问一个指向堆栈变量的指针不会发生段错误,而且很可能在玩具示例中工作。实际上并没有检查您是否访问了空闲堆栈。那太慢了。所以它只是没有,你得到了最后的东西。

要打印的值直接在 main() 中计算,在 x64 中,它将被推送到 printf 调用的槽已经分配在 [=10 的顶部=];因此没有任何机会覆盖该值。但是,如果进程在此期间接收到信号,则该值将在信号处理程序中被踩踏,您对此无能为力。

只是为了证明这是未定义的行为我 运行 你的代码是这样的,得到你的结果 = 1

然后我运行这个代码

int main() {
    num* n = malloc(sizeof(num));
    init_struct(n);
    fopen("not here", "r"); <<<<====
    printf("%d\n", (n->c)->a);
    return 0;
}

得到了

 -242574432

你得到了最糟糕的 UB,它看起来工作正常,但它会在你最苛刻的客户最繁忙的一天中失败