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
。为什么会这样?
答案 0 :(得分:4)
这是因为undefined behavior。
对于C标准,没有“垃圾”值的定义或概念(例如,可以称为垃圾或类似的值的范围)。行为未定义,因此任何事情都可能发生。无法保证在调用UB之后,程序将(或不会)继续执行以生成(或不生成)任何输出。
相关,引用C11
,章节§3.4.3,未定义行为
- 1 未定义的行为
行为,在使用不可移植或错误的程序结构或错误数据时, 本国际标准没有要求
- 2 注意
可能的未定义行为包括完全忽略不可预测的情况 结果,在翻译或程序执行过程中以文件化的方式表现 环境(有或没有发出诊断信息),终止翻译或 执行(发出诊断信息)。
答案 1 :(得分:0)
在这种情况下,您将内存位置从被调用的堆栈帧分配到p
中的f
。当您调用printf
时,f
之前使用的堆栈帧现在由printf
使用,在您的情况下,它会被零覆盖。
问题是,您在f
中分配了一个以后的无效内存位置,因为在返回函数后您不能访问函数的变量。