为什么这段代码不会返回垃圾值?

时间:2017-03-14 06:30:53

标签: c function pointers undefined-behavior

void f(int **pp)
{
   int q = 10;
  *pp = &q;
}

int main()
{
  int a = 5;
  int *p = &a;
  f(&p);
  printf("%d", *p);
  return 0;
}

在编译时,此代码返回0,因为堆栈变量q在删除堆栈帧后消失。

但是,作为一个悬空指针,我想它也可能会返回一些垃圾值。

但是,我在不同的编译器上编译它,它们都返回0。为什么会这样?

2 个答案:

答案 0 :(得分:4)

这是因为undefined behavior

对于C标准,没有“垃圾”值的定义概念(例如,可以称为垃圾或类似的值的范围)。行为未定义,因此任何事情都可能发生。无法保证在调用UB之后,程序将(或不会)继续执行以生成(或不生成)任何输出。

相关,引用C11,章节§3.4.3,未定义行为

  
      
  • 1 未定义的行为
  •   
     

行为,在使用不可移植或错误的程序结构或错误数据时,   本国际标准没有要求

     
      
  • 2 注意
  •   
     

可能的未定义行为包括完全忽略不可预测的情况   结果,在翻译或程序执行过程中以文件化的方式表现   环境(有或没有发出诊断信息),终止翻译或   执行(发出诊断信息)。

答案 1 :(得分:0)

在这种情况下,您将内存位置从被调用的堆栈帧分配到p中的f。当您调用printf时,f之前使用的堆栈帧现在由printf使用,在您的情况下,它会被零覆盖。

问题是,您在f中分配了一个以后的无效内存位置,因为在返回函数后您不能访问函数的变量。