2012-01-05 30 views
13

说我有以下两个功能:用C局部变量的寄信人地址

int * foo() 
{ 
    int b=8; 
    int * temp=&b; 
    return temp; 
} 

int * foo() 
{ 
    int b=8; 
    return &b; 
} 

我没有得到任何预警第一个(例如函数返回本地变量的地址)但是我知道ow这是非法的,因为b从堆栈中消失,我们剩下一个指向未定义内存的指针。

所以,当我需要小心返回临时值的地址?

回答

17

你没有得到的第一个片段一个警告的原因是因为你不是(从编译器的角度来看)返回一个地址给一个局部变量。

您正在返回的int * temp值。尽管这个变量可能是(并且在这个例子中是)包含一个作为局部变量地址的值,但编译器不会上去执行代码栈来查看是否是这种情况。

注意的片断两者都同样糟糕,即使你的编译器不会警告你了前者。不要使用这种方法。


返回局部变量的地址时,你一定要加倍小心;作为一项规则,你可以说你从来没有应该。

static变量是一个完全不同的情况下,虽然,这是在this thread正在讨论之中。

+1

谢谢!以及当我在主打印返回值的时候,它会得到正确的结果,这实际上意味着它打印垃圾? – mary 2012-01-05 13:42:24

+3

这意味着你正在调用我们通常所说的* [未定义的行为](http://en.wikipedia.org/wiki/Undefined_behavior)*,即。在标准中未指定的行为。 – 2012-01-05 13:46:23

-2

这些都是坏的,一个好的编译器应该能够探测和警告两种情况。您可以通过将警告级别设置为最大值(您始终应该这样做)来获得更好的结果,并打开优化。

+0

具体情况,也许。但是也有很多类似的情况涉及将地址与其他变量(或通过其他函数)进行混洗,而编译器根本无法检测到这些变量。此外,优化很少会增加检测此类问题的几率 - 它只会增加出现可观察效果的问题的可能性。 – Rob 2015-02-03 00:07:53

+0

当然,有些编译器无法检测的情况,但这些特定情况应该很容易检测到。优化是有效的,因为它将第一个例子减少到第二个例子 – harald 2015-02-04 08:45:40

+1

对不起,不对。当谈到编译器的实施质量时,几乎没有“应该” - 这些都是基于他们自己的成本/收益分析的供应商决策,这可能不符合开发人员的先入之见。构造示例(例如可能会改变指针的函数调用)也很容易,这意味着您声称的优化可能不可行 - 这也使得供应商决定是否优化这些事情,而不是给定的。 – Rob 2015-02-04 09:05:28

0

这两个示例同样不正确。我的猜测是你的编译器没有看到危险,因此当你将地址存储在临时变量中时不会发出警告。

1

我要说的是,你可以返回局部变量或者说指针,例如,如果它是通过动态分配的malloc,在这种情况下,用于存储变量的存储要放在栈但堆和不会被清零或在退出函数后重新使用,因为它在自动局部变量(没有malloc创建)的情况下发生,我说得对吗?