Ç - 返回本地指针VS局部变量

问题描述:

我的问题是关于这两种情况下:Ç - 返回本地指针VS局部变量

#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; 
} 

案例1:当它与foo1()的情况下,我们得到的,因为我们正试图返回一个错误地址拷贝到主其数据已被删除(当我们退出foo1()函数)

案例2:但在foo2的(),它不给虽然我们正在返回副本错误数据将被删除的局部变量的指针d在我们退出foo2()函数后,为什么会这样?

TL; DR:为什么foo2()不给出错误,但foo1()呢?

TIA。

+0

C或C++?另外,g ++,[给出两者的警告](http://coliru.stacked-crooked.com/a/5ee45849a93cd26d) – NathanOliver

+0

我相信这与* foo1 *返回一个右值而* foo2 *返回一个左值,即使指针地址本身无效,该值也是有效的返回值。 – abe

+0

为什么是双标签? – StoryTeller

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

您不允许使用解除引用指向指向自动存储持续时间不在范围内的变量的指针。

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

+0

有用的答案 - 我总是三重检查我的代码,以确保我的猫不会被编译器吃掉。 – Peri461

+0

我也是;从研究中删除了我的猫。 – Bathsheba

+0

我们当然应该避免编码做法,导致编译器吃猫! :O –

在这两种情况下,您都会调用undefined behavior,方法是返回一个指向局部变量的指针并对其进行解引用。

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

做出看似无关的更改(如添加未使用的局部变量或用于调试)可以改变未定义行为的体现方式。

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

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

两个案例1和情况2是不确定的行为,你不能返回指向局部变量