为什么自动对象的值在生命结束后仍然存在?

时间:2014-01-28 14:12:16

标签: c output

我准备面试。

我的c程序是:

void foo(void)
{
    int a;
    printf("%d\n",a);
}

void bar(void)
{
    int a=42;
}

void main(void)
{
    bar();
    foo();
}

我得到的输出为:42

但是怎么样?我认为这将是一些垃圾价值。

如何应用执行堆栈或激活框架的概念?

请解释

由于

3 个答案:

答案 0 :(得分:5)

a未在函数foo中初始化。打印未初始化的变量会调用未定义的行为 在这种情况下,您可能得到任何预期或意外结果。在我的编译器上,输出是

 4203214  

结果可能会因编译器与编译器而异,即使同一编译器的不同版本也会给您不同的结果 但是获得42的可能原因之一是因为自动变量通常在执行堆栈上分配。在调用bar之后,42被放置在执行堆栈上。该值保持不受干扰。调用foo时,可能读取a的堆栈空间并打印42
尝试优化代码(使用-o编译),您可能会为a获得一些不同的值。

答案 1 :(得分:3)

bar()的调用将值42放在堆栈上。调用foo()时仍然存在。

bar()foo()的堆叠帧可能相同或至少相似,因此a中的foo()保留值42

当然,这不能保证,并且是未定义的行为。但是,对于调试代码,通常需要一些理解,而不是像通常那样简单地解决这些问题。

如果您提高优化级别(至少在gcc中),您看到的行为将会改变。

答案 2 :(得分:1)

当您从bar()致电main()时,它会将a = 42设置在堆栈上,从main()执行的位置开始。当您从foo()调用main()时,它会打印a的值,该值在此范围内也是从main()执行的位置开始的一个int。

首先调用bar(),您已在堆栈上设置数据,并且由于foo()bar()具有相同的调用框架,bar()的{​​{1}} }和a的{​​{1}}最终位于相同的内存地址中。

正如其他答案所指出的那样,这是未定义的行为。在这种情况下,该值将持续存在于堆栈中并最终位于同一位置。