C++中不应该返回局部变量的地址
来源:互联网 发布:怎么联系淘宝店铺客服 编辑:程序博客网 时间:2024/06/06 06:50
最近在写代码的时候遇到返回局部变量的引用问题,认识不是很清晰,下面是转自http://blog.csdn.net/tujinqiuqq85948239/article/details/27236677博文的详细解释!
在Effective C++中明确指出:不应该返回局部变量的引用,原因在于:局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无所指”的引用,程序会进入未知状态。如果比较理解函数局部变量的作用域和生命周期,那么这一点很好理解。
在C++中,实际上引用和指针类似,都是变量的实际存储地址。既然不能返回局部变量的引用,如下所示,这样做是不合理的:
int &getRefer() { int pp = 8; return pp;}
所以,返回局部变量的地址作为指针也是不合理的:
int *getPoint() { int pp = 8; return &pp; }
返回的地址指向一个过期的对象,后面可能发生不可预知的行为。
但是当我在VC中写下如下代码:
int &getRefer() { int pp = 8; return pp;}int main() { int &ppp = getRefer(); ppp = ppp + 3; return 0;}
你会发现,编译器会警告:试图返回局部变量的地址,但是还是可以编译通过。运行的时候,int &ppp = getRefer()语句之后,ppp确实等于8,ppp = ppp + 3之后,ppp确实等于11,奇怪了,当时我就想难道这个局部变量起死回生了???怎么还能这么正常的使用???那为什么编译器又会警告了呢?我查了好多资料,才发现这和函数调用时栈指针的处理方式有关:
当你调用getRefer函数时,函数栈指针会根据函数里面的局部变量的内存分配(编译器自动分配)而依次向后移动,当函数调用完毕,栈指针回撤,回撤到外部调用函数的地方,这个时候,函数局部变量,比如这里的ppp使用的内存已经被收回(ppp的生命周期已经结束),但是这个内存里面的内容还是8,所以ppp确实指向这块内存,而且内存存储的内容没有发生改变。所以造成一种假象,就是我们以为局部变量的生命周期延长了。
这快内存我们可以使用诸如上面所示的ppp = ppp + 3来修改内容,但是这块内存的所有权并不在我们手里,而是在系统手里,系统随时有可能改变这块内存中的内容。所以我们说后面的结果是不可预知的。下面我来说明如何演示系统会改变这块内存的内容:
如下面代码段所示:
int &getRefer() { int pp = 8; return pp;}int shiyi() { int temp1 = 100; int temp2 = 200; return temp1 + temp2; } int main() { int &ppp = getRefer(); int temp = shiyi(); ppp = ppp + 3; return 0;}
这里与前面的区别仅仅在于在getRefer函数调用之后,又调用了一个与它完全不相关的函数shiyi。
我们在getRefer函数调用之后,发现ppp = 8,这是因为系统还没有覆盖使用这块内存,然后我们调用shiyi函数,如前面所述,函数内部会给局部变量分配栈内存,函数栈指针后移,这个时候,系统很有可能就使用了前面ppp = 8的这块内存,这里在调用shiyi之后,你会发现ppp的值也跟着变成了200!!!这是因为编译器在调用shiyi函数的时候将ppp指向的内存由8改成了200!!!这就是前面所说的不可预料的结果,因为你不能知道这个ppp会怎么变化,它完全不受控制,调用任何一个函数或者其他行为都有可能覆盖这块内存。
所以不要试图返回一个局部变量的引用,也不要试图返回一个指向局部变量的指针,用一句话说就是不要返回一个局部变量的地址。
- C++中不应该返回局部变量的地址
- C++中不应该返回局部变量的地址
- C语言--返回局部变量的地址
- C语言中返回局部变量或临时变量的地址的错误
- 返回局部变量的地址
- 局部变量地址的返回
- C语言函数不能返回局部变量的地址
- C基础----返回局部变量的地址&栈(linux)
- C语言函数不能返回局部变量的地址
- C语言中关于函数的局部变量和地址返回
- 注意不要返回局部变量的地址
- C语言中函数返回局部变量的方法
- C/C++中函数返回局部变量的问题
- c/c++ 函数中局部变量的返回
- C语言函数中局部变量的返回
- c语言中关于局部变量的返回值
- C语言中局部变量的地址覆盖问题
- C/C++ waring:返回局部变量或临时变量的地址
- [mongdb]安装mongodb和将mongdb设置为windows服务
- 2012-ImageNet数据集冠军AlexNet论文英文原文及AlexNet分析
- 【深度学习框架Caffe学习与应用】第四课 Caffe可视化工具
- 【BZOJ3294】放棋子(CQOI2011)-DP+组合数学
- 关于自定义TextView的测量问题
- C++中不应该返回局部变量的地址
- HTTP协议
- 图解机器学习
- 9.1数字三角形(记忆化搜索与递推)
- 论文结果难复现?本文教你完美实现深度强化学习算法DQN
- Android事件分发机制
- StackOverFlow提问的艺术
- PC端连接Android设备进行adb调试
- C语言使用openssl库进行加密