我有下面的代码。

#include <iostream>

int * foo()
{
    int a = 5;
    return &a;
}

int main()
{
    int* p = foo();
    std::cout << *p;
    *p = 8;
    std::cout << *p;
}

并且代码正在运行,没有运行时异常!

输出是58

怎么可能呢?局部变量的内存在其函数之外不是不可访问的吗?


当前回答

在c++中,你可以访问任何地址,但这并不意味着你应该这样做。您正在访问的地址不再有效。它之所以能工作,是因为在foo返回后没有其他东西扰乱内存,但在许多情况下它可能崩溃。试着用Valgrind分析你的程序,甚至只是优化编译它,然后看看…

其他回答

你只是返回一个内存地址,这是允许的,但可能是一个错误。

是的,如果你试图解引用该内存地址,你将有未定义的行为。

int * ref () {

 int tmp = 100;
 return &tmp;
}

int main () {

 int * a = ref();
 //Up until this point there is defined results
 //You can even print the address returned
 // but yes probably a bug

 cout << *a << endl;//Undefined results
}

因为存储空间还没有被践踏。不要指望那种行为。

它之所以能工作,是因为自从a被放入堆栈以来,堆栈(还没有)被改变过。 在再次访问a之前调用一些其他函数(它们也调用其他函数),你可能不会再那么幸运了……: -)

给所有的答案补充一点:

如果你这样做:

#include<stdio.h>
#include <stdlib.h>
int * foo(){
    int a = 5;
    return &a;
}
void boo(){
    int a = 7;

}
int main(){
    int * p = foo();
    boo();
    printf("%d\n",*p);
}

输出可能是:7

这是因为从foo()返回后,堆栈被释放,然后被boo()重用。 如果你分解可执行文件,你会清楚地看到它。

在c++中,你可以访问任何地址,但这并不意味着你应该这样做。您正在访问的地址不再有效。它之所以能工作,是因为在foo返回后没有其他东西扰乱内存,但在许多情况下它可能崩溃。试着用Valgrind分析你的程序,甚至只是优化编译它,然后看看…