c++里返回函数局部变量的地址的有关问题

c++里返回函数局部变量的地址的问题。
c++里返回函数局部变量的地址(指针)是什么样的道理呢?用了函数,局部变量应该就没了。我试了一下,不知道为什么是这样,请达人解释一下。谢谢。↓↓↓
C/C++ code

#include "stdafx.h"
#include <iostream>
using namespace std;

int* test()
{
    int i=20;
    return &i;
}

void main()
{
    int *p=test();//把局部变量的地址给了p
        cout<<p<<endl;//这句话如果不注释,那就打印p存储的那个变量的地址假设为A。
    cout<<*p<<endl;//不注释上面那句,然后运行这句打印的数据不是20,是一个很大的数字
                          //应该是变量没了,指针乱指了吧。但是如果不运行上面那句,先打印值,可以正确显示20。为什么呢
    cout<<p<<endl;//再打印地址,还是之前那个地址A。局部变量不是没了吗?怎么还有地址可以打印呢?
}



------解决方案--------------------
局部变量是在stack中的,不是没有了,而是说无效了!

无效的意思是,你不能保证什么时候,stack中的那个值就会被别的函数调用覆盖。应为一个线程中各个函数共用一个stack。

这也就是为什么调用第二句cout<<p<<endl后stack中的20就被覆盖了。

所以不返回局部变量的地址是对的。

另外地址是这个stack中的地址,是不会和地址中存的对应内容相关的,所以地址是不会变的。

最后建议楼主多看看C语言指针。有时间看看汇编就更加明白了。
------解决方案--------------------
C/C++ code

栈向内存低地址处增长

在main内时,栈是这样的
栈                   内存地址
main
    +----------+
    | 保存ebp  |
    +----------+ --> 0x12ff80
  p |    ?     |
    +----------+ --> 0x12ff7c  <-- 栈指针
         。
         。
         。

当运行到int *p=test();进入到test函数内时,栈要增长,栈指针-???, 为test开辟局部变量空间,

栈                   内存地址
main
    +----------+
    | 保存ebp  |
    +----------+ --> 0x12ff80
  p |    ?     |
    +----------+ --> 0x12ff7c
         。
         。
test     。
    +----------+
    | 保存ebp  |
    +----------+ --> 0x12ff28
  i |    20    |
    +----------+ --> 0x12ff24  <-- 栈指针

返回时,将地址0x12ff24保存到变量p的内存,栈指针+???,释放test的栈空间,退栈,但是内存里的那些内容还是保持不变的。所以会输出0x12ff24处的内存数据20。

栈                   内存地址
main
    +----------+
    | 保存ebp  |
    +----------+ --> 0x12ff80
  p | 0x12ff24 |
    +----------+ --> 0x12ff7c
         。
         。          0x??????  <-- 栈指针
         。
    +----------+
    |还是那个数|
    +----------+ --> 0x12ff28
    |    20    |
    +----------+ --> 0x12ff24 

如果你又定义了一个test2
int *test2()
{
    int i = 30;
    return &i;
}

main函数改成这样的
void main()
{
    int *p=test();//把局部变量的地址给了p
    test2();
    //cout<<p<<endl;//这句话如果不注释,那就打印p存储的那个变量的地址假设为A。
    cout<<*p<<endl;//不注释上面那句,然后运行这句打印的数据不是20,是一个很大的数字
    //应该是变量没了,指针乱指了吧。但是如果不运行上面那句,先打印值,可以正确显示20。为什么呢
    cout<<p<<endl;//再打印地址,还是之前那个地址A。局部变量不是没了吗?怎么还有地址可以打印呢?
}

运行到test2函数内时,栈指针-???,开辟局部变量空间,栈空间会覆盖先前的数据,test2中的i的地址就会是0x12ff24,就会把0x12ff24处的内存改为30,所以cout<<*p<<endl;会输出30。

这样的解释可能会让你云里雾里,先解释这些,有不明白的再说了,我先忙了 :)