我的问题是关于这两种情况:
#include <stdio.h>
int *foo1();
int *foo2();
int main()
{
printf("so it's %d\n",*foo1());
printf("so it's %d\n",*foo2());
}
int *foo1()
{
int i1 = 5;
return &i1;
}
int *foo2()
{
int i2 = 5;
int *p = NULL;
p = &i2;
return p;
}
case1:当它与foo1()的情况一样时,我们得到一个错误,因为我们试图将一个地址副本返回给main,其数据已被删除(当我们退出foo1()函数时)
case2:但是在foo2()中,没有给出错误虽然我们将副本返回到局部变量的指针,其数据将在删除后删除我们退出foo2()函数,为什么会这样?
TL; DR:为什么foo2()没有给出错误,但是foo1()呢?
TIA。
答案 0 :(得分:8)
在C和C ++中,函数foo1
和foo2
的行为都是 undefined 。
您不能取消引用一个指针,该指针指向一个自动存储持续时间不再在范围内的变量。
明天,foo2()
也可能会给你一个错误。或者编译器可能会吃你的猫。
答案 1 :(得分:1)
在这两种情况下,您都通过返回指向局部变量的指针并取消引用它来调用undefined behavior。
调用未定义的行为并不意味着您将始终崩溃。这意味着程序的行为是不确定的。它可能崩溃,它可能会输出奇怪的结果,或者它似乎可以正常工作。如您所见,此行为在您的程序中以其中两种方式表现出来。
进行看似无关的更改,例如添加未使用的局部变量或printf
进行调试,可以改变未定义行为的显示方式。
答案 2 :(得分:1)
两者都是未定义的行为,您不能依赖编译器为您提供未定义行为的警告。
你实际上在两个函数中做同样的事情,实际上两者都可能导致生成相同的汇编代码。
答案 3 :(得分:1)
case1和case2的行为都是未定义的,你不能返回指向局部变量的指针