2012-01-03 64 views
3

可能重复:
Returning the address of local or temporary variable
Can a local variable's memory be accessed outside its scope?有什么不对?悬挂指针?

#include<iostream> 
using namespace std; 

int *p = NULL; 

void 
fun(void){ 
    int i = 10; 
    p = &i; 
} 

int 
main(void){ 
    fun(); 
    cout<<*p<<endl; //#1 
    cout<<*p<<endl; //#2 
    return 0; 
} 

我觉得#1和#2将输出相同,但为什么#1输出10和#2输出随机数?

+5

您正在创建一个指向堆栈变量的指针,该堆栈变量被销毁,然后取消引用指针,产生未定义的行为 – 2012-01-03 15:52:51

+1

未定义的行为,这意味着您可以获得预期的输出(http://ideone.com/VMYzG)或某些其他结果(http://codepad.org/OiN8n1L0) – UncleBens 2012-01-03 16:20:27

回答

8

这只是未定义的行为。在变量超出范围之后,您正在使用指向局部变量的指针。什么事情都可能发生。

+0

所以#1应该输出一个随机数? – bitstore 2012-01-03 15:58:50

+2

@tinybit:你需要认识到,对于“应该”发生什么是没有意义的。这是**未定义的行为**。 – unwind 2012-01-03 15:59:50

+0

@tinybit:它不应该做任何具体的事情。 “什么事情都可能发生”。 – 2012-01-03 16:00:02

1

是的,pfun()返回时成为悬挂指针。

1

您正在保存一个指向超出范围的变量的指针。因此,behavior is undefined。它可以打印任何内容,甚至可能导致应用程序崩溃甚至让你的电脑爆炸。

3

这确实是一个悬挂指针。

您正在分配p指向自动(本地)对象。一旦fun已返回,该对象不再存在,并试图通过p访问它给出未定义的行为。

如果您对观察特定行为的原因感兴趣:在大多数平台上,fun的堆栈帧将一直存在,直到调用另一个函数。因此,第一次拨打<<时,p的读数很可能会找到旧值i。在调用<<之后,旧的堆栈帧很可能被覆盖,因此读取p将找到任意值。但这些都不是你可以依赖的行为;访问死对象可能导致崩溃或任何其他行为。

+0

+1用于说明输出的可能原因。虽然不能依赖UB,但需要能够识别影响。 – UncleBens 2012-01-03 16:24:37

1

你的函数返回一个指针的东西得到过书面:

int i = 10; 
p = &i; // This line 

因为i是一个局部变量。