2012-01-03 100 views
2

可能重复:
Returning the address of local or temporary variable
Can a local variable's memory be accessed outside its scope?返回指向本地函数变量

我知道我不应该返回指针的本地函数变量(局部堆栈变量),因为当函数返回,变量将是无效的,堆栈将被清除,除非我使这些变量为静态或将它们分配在堆上。

下面的代码表明:

const char* v1() { 
    return "ABC"; 
} 

const char* v2() { 
    string s = "DEF"; 
    return s.c_str(); 
} 

const char* v3() { 
    static string s = "JHI"; 
    return s.c_str(); 
} 

cout << v1() << endl; // Output: ABC 
cout << v2() << endl; // Output: garbage (♀ ╠╠╠╠╠╠╠╠) 
cout << v3() << endl; // Output: JHI 

然而,我返回的指针到原始的本地函数变量,我能得到它的价值,虽然它不是一成不变的,如下面的代码所示:

int i1() { 
    int i = 5; 
    return i; 
} 

int* i2() { 
    int i = 6; 
    return &i; 
} 

int* i3() { 
    static int i = 7; 
    return &i; 
} 

cout << i1() << endl; // Output: 5 
cout << *i2() << endl; // Output: 6 !! 
cout << *i3() << endl; // Output: 7 

编译器只给我警告我是返回本地变量或临时地址(Visual C++ 2008)。这种行为对于所有编译器是否共同以及编译器如何允许我使用指向本地函数变量的指针来访问它指向的值,尽管当函数返回时该变量是无效的?

+3

它的值恰好在相同位置的内存中。这个工作的事实是一个意外,或者是在“调试”模式下编译的结果。我不确定问题是什么 - 你已经知道你不应该这样做。听你的编译器发出的警告! – 2012-01-03 06:42:41

回答

2

它可以从堆栈中移除,因为它是本地的,但值会一直保留到另一个覆盖它为止。 它是C++不安全的语言,你可以做很多奇怪的事情

2

你返回一个地址。返回地址有效 - 始终。但就你而言,你也可以对它进行解除引用。这是未定义的行为。理论上,对于未定义的行为,任何事情都可能发生。编译器甚至允许嵌入代码来格式化硬盘。实际上,它将取消引用地址而不进行任何检查。如果它仍然可以访问,它会返回该地址的值,否则会导致访问冲突。

您的地址位于堆栈上,因此始终可以访问。根据您在两者之间进行的调用,值可能仍然存在或不存在。所以在简单的情况下,你可以获得价值回报,在更复杂的情况下,你不会。它甚至可能有时有效,有时它不会。

有关详细信息,您应该阅读一些关于如何在汇编程序中调用函数以了解编译器在堆栈中执行的操作的信息(放置参数,返回地址,放置局部变量,返回时清除堆栈,调用约定)。