函数返回后,局部变量仍然存在

时间:2012-10-15 18:03:21

标签: c local-variables

我认为一旦函数返回,所有声明的局部变量(禁止带有static关键字的变量)都是垃圾收集的。但是当我尝试下面的代码时,它仍会在函数返回后打印该值。任何人都可以解释原因吗?

int *fun();
main() {
  int *p;
  p = fun();
  printf("%d",*p); //shouldn't print 5, for the variable no longer exists at this address
}
int *fun() {
  int q;
  q = 5;
  return(&q);
}

5 个答案:

答案 0 :(得分:7)

C中没有垃圾收集。一旦变量的范围不复存在,以任何方式访问它都是非法的。你看到的是UB(未定义的行为)。

答案 1 :(得分:6)

这是未定义的行为,任何事情都可能发生,包括出现在工作中。内存可能还没有被覆盖,但这并不意味着你有权访问它。但你做到了!我希望你快乐! :)

答案 2 :(得分:5)

如果您确实希望松散该值,可能会调用其中至少包含几行代码的其他函数,然后通过访问该位置执行printf 很可能到那时你的价值就会被写下来。

但是如上所述,这已经是未定义的行为。你永远无法预测它何时崩溃或变化。但是你不能依赖它“改变或保持不变”并用任何这些假设对应用程序进行编码。

我想说明的是,当你从前一个函数返回后再进行另一个函数调用时,另一个激活记录被推送到堆栈,很可能是写入前一个,包括你通过指针访问其值的变量

一旦一个函数及其数据超出范围,任何实体都不会实际上是垃圾收集或者说memset 0。

答案 3 :(得分:2)

C不支持Java支持的垃圾收集。阅读有关垃圾收集的更多信息here

答案 4 :(得分:1)

逻辑q退出时fun不再存在。

物理上(对于"物理"的适当松散定义),故事有点复杂,并且取决于底层平台。 C不进行垃圾收集(在这种情况下不适用垃圾收集)。 q占用的内存单元(虚拟或物理)仍然存在并包含上次写入的任何值。根据架构/操作系统/任何内容,您的程序仍然可以访问 单元格,但不能保证:

6.2.4对象的存储持续时间

2对象的生存期是存储期间程序执行的一部分 保证为它保留。存在一个对象,具有一个常量地址, 33) 并保留 它在其整个生命周期中的最后存储值。 34) 如果某个对象被引用到其外部 一生,这种行为是未定的。当指针变为不确定时,指针的值变得不确定 它指向(或刚刚过去)的对象到达其生命周期的末尾。
33)术语“常量地址”意味着指向对象的两个指针可能不同 时间会比较平等。在两次不同的执行期间,地址可能不同 节目。

34)对于易失性对象,最后一个商店不需要在程序中显式。

"未定义的行为"是C语言通过不处理问题来处理问题的方法。基本上,实现可以自由地以任何方式处理这种情况,直到完全忽略问题并让底层操作系统杀死程序来做一些顽皮的事情。

在您的特定情况下,fun退出后访问该内存单元并没有破坏任何内容,并且尚未覆盖。这种行为不能保证可重复。