c++里返回函数局部变量的地址的有关问题
c++里返回函数局部变量的地址的问题。
c++里返回函数局部变量的地址(指针)是什么样的道理呢?用了函数,局部变量应该就没了。我试了一下,不知道为什么是这样,请达人解释一下。谢谢。↓↓↓
------解决方案--------------------
局部变量是在stack中的,不是没有了,而是说无效了!
无效的意思是,你不能保证什么时候,stack中的那个值就会被别的函数调用覆盖。应为一个线程中各个函数共用一个stack。
这也就是为什么调用第二句cout<<p<<endl后stack中的20就被覆盖了。
所以不返回局部变量的地址是对的。
另外地址是这个stack中的地址,是不会和地址中存的对应内容相关的,所以地址是不会变的。
最后建议楼主多看看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。 这样的解释可能会让你云里雾里,先解释这些,有不明白的再说了,我先忙了 :)