关于返回局部变量的引用的疑问??

gluckm 2006-08-24 09:46:51
#include <iostream>
#include <math.h>
using namespace std ;

double& Sum(int iNum)
{
int iBase = 2 ;
int iTemp = 0 ;
double iSum = 0 ;
double& s = iSum ;
for (int i = 0; i < iNum; i ++)
{
iTemp = iTemp + iBase * pow(10, i) ;
iSum = iSum + iTemp ;
}
return s ;
}


void main()
{
int iNumber ;
double sum ;
cout<< "Please input the number of jishu: " <<endl ;
cin>> iNumber ;
sum = Sum(iNumber) ;
cout<< "The sum is: " << sum <<endl ;
}

以上是我的代码,在vc6.0下通过(题目是求和 a+aa+aaa+aaaa+...)
我之前在effective c++上看见过这样的说法,不要返回局部变量的引用,因为栈上生成的局部变量在函数调用结束后会被析构掉,从而导致返回的引用指向一个不存在的变量(说法可能不太准确,但是我的意思就是这样),从而导致错误!
但是现在这个小代码可以编译通过并且得出正确结果(因为没考虑溢出,所以请输入小一点的数)
这到底是怎么回事情?
请高人指点一二,在线等待,谢谢!
...全文
402 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
gluckm 2006-08-24
  • 打赏
  • 举报
回复
我仔细研究下
a_b_c_abc6 2006-08-24
  • 打赏
  • 举报
回复
能得到正确结果,不表明没有错误。

楼主的程序之所以能得到正确的结果,主要是因为这句sum = Sum(iNumber) ;,使返回的值已经转移到sum上。输出的sum也不是函数中的 iSum ,而是另外一个地方的相同值。

下面这处程序你就能看到返回的引用已经被覆盖的情况:


#include <iostream>
#include <math.h>
using namespace std ;

double& Sum(int iNum)
{
int iBase = 2 ;
int iTemp = 0 ;
double iSum = 0 ;
double& s = iSum ;
for (int i = 0; i < iNum; i ++)
{
iTemp = iTemp + iBase * pow(10, i) ;
iSum = iSum + iTemp ;
}
return s ;
}

void test()
{
int x=0,y=0,z=0,a=0,b=0,c=0;
}

void main()
{
int iNumber ;
cout<< "Please input the number of jishu: " <<endl ;
cin>> iNumber ;
double &sum = Sum(iNumber) ;//sum是局部变量的引用
test();//当另一个函数又展开栈时,将覆盖先前的函数栈上的数据
cout<< "The sum is: " << sum <<endl ;//这里输出的也就不是正确结果了,而是0,如果注释掉上一行的test()调用,则可以得到正确结果,但仍然是属于过期数据,程序上中应该避免。
}


gluckm 2006-08-24
  • 打赏
  • 举报
回复
弱弱的问下,我在debug模式下查看的时候,发现该段地质空间在函数返回后,iSum地址里面的值并没有恢复为cc,这样的话,好像就跟上面的各位所说的有点出入了??
睡在床板下_ 2006-08-24
  • 打赏
  • 举报
回复
恩,我的理解是这样子的
gluckm 2006-08-24
  • 打赏
  • 举报
回复
哦,原来如此,多谢各位的指教! THK...
gluckm 2006-08-24
  • 打赏
  • 举报
回复
corrupt(喜欢 睡在床板下 的思考)
你的 意思是不是 因为原来储存 iSum 的那段地址空间还没有被别的代码应用,里面存储的值还么有被覆盖,所以才会得到正确的结果? 如果折断地址空间被分配给别的代码后,才会出现错误??
Heaven_Redsky 2006-08-24
  • 打赏
  • 举报
回复
说到底 得到正确结果 是幸运的表现:)
Heaven_Redsky 2006-08-24
  • 打赏
  • 举报
回复
UPCC(杂食动物)的说法是正确的
就是因为是小程序 所以会得到正确结果
如果是大程序 可能就会出现意想不到的错误 因为那个地址的值就会被别的内容覆盖掉
睡在床板下_ 2006-08-24
  • 打赏
  • 举报
回复
s引用的是iSum ,而iSum 的定义是
double iSum = 0 ;
引用就和指针差不多...堆栈展开就就消失了就是堆栈的栈顶指针是已经回到原来的地方了.
可是 s 所指的 地址的值没有改变(除非被覆盖), 所以就是如上的结果了
gluckm 2006-08-24
  • 打赏
  • 举报
回复
但是我的&s = iSum;的阿
楼上的可能没明白,我的小代码是可以得到正确结果的,并没有出现错误的阿!!
我想问的是为什么没有出现 不要返回局部变量的引用 的错误??
Dong 2006-08-24
  • 打赏
  • 举报
回复
数调用结束后会被析构掉,从而导致返回的引用指向一个不存在的变量(说法可能不太准确,但是我的意思就是这样),从而导致错误!
--------------------------------
s引用的是iTemp ,而iTemp 的定义是
int iTemp = 0 ;
这个iTemp 在函数Sum退出时堆栈展开就就消失了,所以返回的s是没有存在真实值了
gluckm 2006-08-24
  • 打赏
  • 举报
回复
a_b_c_abc6() 所得不错,
非常谢谢你的指教,不过抱歉之前把分都分完了,sorry
THK!

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧