我知道一个事实,即永远不要从函数返回局部变量的地址。但是,在证明事实的同时,我遇到了一个问题。考虑以下程序:
int *test()
{
int x = 12;
int *p = &x;
return p;
}
int main()
{
int *p = test();
printf("%p",p);
return 0;
}
它按预期打印类似0061fed0
的地址。但是,如果我直接使用&
返回x的地址,即test
函数的更改如下:
int *test()
{
int x = 12;
return &x;
}
然后输出将变为00000000
。那么,您能解释一下这里发生了什么吗?我正在使用Windows 10中的Code :: Blocks 17.12 IDE捆绑提供的gcc编译器。
关于重复的问题: 建议重复的问题: C - GCC generates wrong instructions when returning local stack address 说明了直接使用运算符的地址的行为,但没有解决使用指针变量返回局部变量的地址的情况,这在StoryTeller的答案中进行了解释:“当指针变大时,指针的值变得不确定它所指向(或刚刚过去)的对象达到其生命周期的尽头。”
答案 0 :(得分:4)
严格来说,从C语言规范的角度来看,这是一个有效的结果。
6.2.4对象的存储期限(强调我的意思)
2对象的生存期是程序执行的一部分 在此期间,保证为其保留存储空间。一个东西 存在,具有恒定的地址,并保留其最后存储的值 整个生命周期如果在对象之外引用对象 寿命,行为是不确定的。 指针的值变为 不确定它所指向的对象(或刚刚过去的对象)何时到达 寿命结束。
因此,无论哪种情况,函数返回的值都是不确定的。您无法预测它将是什么,甚至无法以有意义的方式使用它。使用不确定值的程序具有不确定的行为,任何事情都可能发生。
因此,当您直接返回本地地址时,编译器将返回null。根据C语言本身,这是一个有效值,因为无论如何该对象很快就会死亡。但是,这样做的好处是,在现代的托管实现中,您可能会在早期使程序崩溃,并允许您修复错误。