C - 返回本地指针与局部变量

时间:2017-06-19 12:50:18

标签: c pointers memory-management function-pointers

我的问题是关于这两种情况:

#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。

4 个答案:

答案 0 :(得分:8)

在C和C ++中,函数foo1foo2的行为都是 undefined

您不能取消引用一个指针,该指针指向一个自动存储持续时间不再在范围内的变量。

明天,foo2()也可能会给你一个错误。或者编译器可能会吃你的猫。

答案 1 :(得分:1)

在这两种情况下,您都通过返回指向局部变量的指针并取消引用它来调用undefined behavior

调用未定义的行为并不意味着您将始终崩溃。这意味着程序的行为是不确定的。它可能崩溃,它可能会输出奇怪的结果,或者它似乎可以正常工作。如您所见,此行为在您的程序中以其中两种方式表现出来。

进行看似无关的更改,例如添加未使用的局部变量或printf进行调试,可以改变未定义行为的显示方式。

答案 2 :(得分:1)

两者都是未定义的行为,您不能依赖编译器为您提供未定义行为的警告。

你实际上在两个函数中做同样的事情,实际上两者都可能导致生成相同的汇编代码。

答案 3 :(得分:1)

case1和case2的行为都是未定义的,你不能返回指向局部变量的指针