千万不能返回局部变量的引用????

时间:2022-07-01 13:39:09
C++ Primer第7章函数一节,讲到返回时,“ 理解返回引用至关重要的是,千万不能返回局部变量的引用”,

意思是返回程序内部定义的变量时可能会出问题,因为当函数执行完毕后,将释放分配给局部对象的存储空间。

此时,对局部对象的引用就会指向不确定的内存。

觉得不能理解。

比如求阶乘时,可以使用迭代函数的方法,程序很简单,代码如下:

#include <iostream>
using namespace std;
long factorial(int n)
{
int i;
long result=1;
for(i=n;i>=1;--i)
result*=i;
return result;
}
int main()
{
int n;
long result;
cout<<"输入n值"<<endl;
cin>>n;
result=factorial(n);
cout<<n<<"的阶乘为"<<endl;
cout<<result<<endl;
return 0;
}
我在函数中定义的result必然是局部变量,但是作为结果,我必须将这个值返回,所以是不是我就违反了千万不能返回局部变量的引用呢,按照书上所说,rensult变量在函数执行完毕后空间就会被释放,那么这段程序就是错的。可是既然程序能运行出正确的结果,那就必然是正确的,真的很矛盾啊。

11 个解决方案

#1


你这个factorial函数返回的是一个long值,而非值的指针或引用。

#2


意思是说,只是函数体内自定义的指针变量不能返回么?

#3


引用 1 楼 sololie 的回复:
你这个factorial函数返回的是一个long值,而非值的指针或引用。

意思是说,只是函数体内自定义的指针变量不能返回么?

#4


返回的是值,而不是指针或引用

#5


“意思是返回程序内部定义的变量时可能会出问题,因为当函数执行完毕后,将释放分配给局部对象的存储空间。此时,对局部对象的引用就会指向不确定的内存。”

你截的这段书中的说明不是很清楚了么,函数返回指针或引用不是不可以,取决于这个引用或指针指向的东西还是否有效,或者说是否还有意义。

// 返回局部变量i的引用
int& func()
{
    int i = 100; // 在栈中创建了i
    return (int&)i; 
} // 函数执行到这里后i申请的栈内存已经被回收,你返回的i的引用就可能引用了一个不确定的值。

 为什么说是不确定的,因为可能这个值还没有被别的程序修改,在别的程序修改它之前它引用的还是100 这个值。

所谓回收内存,并不是把内存里保存的数值清0,而是指你程序申请的这块内存已经不是你的了,别人也能修改它。申请内存就像租房子,操作系统是房东,申请内存就是向房东申请了一件房间,你租了这件房间别人就不能进来,你可以在房间里搞你的勾当。回收内存就是退房,房东会从新把这件房间标记为空房招租,但是房东不会打扫你退的房间,里面你留下的东西还会在里面,你有钥匙(地址)就还能摸进去找东西,直接下一个租户住进去之后,他可能就把你的东西扔出窗外。你想再回来就找不到原来的东西了。你引用的书中这段话意思就是告诫你不要把贵重的东西留在一个已经不属于你的地方,在不属于你的地方放东西,后果只能听天由命。

// 返回局部变量i的指针
int* func2()
{
    int i = 200;
    return &i; // 同理。
}

#6


上面代码仓促说得不对,返回的地址不等于指针变量,不过大体意思就是这样了

#7


引用 4 楼 sunxingzhesun 的回复:
返回的是值,而不是指针或引用

不明白,难道变量的话就不占用某个内存空间,函数结束之后空间就不会被回收了么?

#8


引用 6 楼 sololie 的回复:
上面代码仓促说得不对,返回的地址不等于指针变量,不过大体意思就是这样了

我好像有点明白了,你那两个例子是说返回变量的地址,但是自定义的变量在函数结束之前内存已经被回收了,所以不对;
而我的函数只是将值返回了,跟内存并没有打交道。
不知道这样理解有没有偏差?

#9


函数的返回值保存在栈帧或寄存器中,函数返回前 返回值被保存在栈帧或寄存器中,函数内的局部变量都将被自动销毁(new的除外,new在堆中创建)。
int、float....struct这些是值类型,值类型就直接复制值,值就在寄存器中如同立即数,引用或指针就复制指针,引用或指针指向的东西的有效期得自己把握。

#10


怕俺自己误人子弟,还是等高人给你指点吧

#11


引用 10 楼 sololie 的回复:
怕俺自己误人子弟,还是等高人给你指点吧

我觉得你解释的很清楚,我大概懂了,谢谢你 千万不能返回局部变量的引用????

#1


你这个factorial函数返回的是一个long值,而非值的指针或引用。

#2


意思是说,只是函数体内自定义的指针变量不能返回么?

#3


引用 1 楼 sololie 的回复:
你这个factorial函数返回的是一个long值,而非值的指针或引用。

意思是说,只是函数体内自定义的指针变量不能返回么?

#4


返回的是值,而不是指针或引用

#5


“意思是返回程序内部定义的变量时可能会出问题,因为当函数执行完毕后,将释放分配给局部对象的存储空间。此时,对局部对象的引用就会指向不确定的内存。”

你截的这段书中的说明不是很清楚了么,函数返回指针或引用不是不可以,取决于这个引用或指针指向的东西还是否有效,或者说是否还有意义。

// 返回局部变量i的引用
int& func()
{
    int i = 100; // 在栈中创建了i
    return (int&)i; 
} // 函数执行到这里后i申请的栈内存已经被回收,你返回的i的引用就可能引用了一个不确定的值。

 为什么说是不确定的,因为可能这个值还没有被别的程序修改,在别的程序修改它之前它引用的还是100 这个值。

所谓回收内存,并不是把内存里保存的数值清0,而是指你程序申请的这块内存已经不是你的了,别人也能修改它。申请内存就像租房子,操作系统是房东,申请内存就是向房东申请了一件房间,你租了这件房间别人就不能进来,你可以在房间里搞你的勾当。回收内存就是退房,房东会从新把这件房间标记为空房招租,但是房东不会打扫你退的房间,里面你留下的东西还会在里面,你有钥匙(地址)就还能摸进去找东西,直接下一个租户住进去之后,他可能就把你的东西扔出窗外。你想再回来就找不到原来的东西了。你引用的书中这段话意思就是告诫你不要把贵重的东西留在一个已经不属于你的地方,在不属于你的地方放东西,后果只能听天由命。

// 返回局部变量i的指针
int* func2()
{
    int i = 200;
    return &i; // 同理。
}

#6


上面代码仓促说得不对,返回的地址不等于指针变量,不过大体意思就是这样了

#7


引用 4 楼 sunxingzhesun 的回复:
返回的是值,而不是指针或引用

不明白,难道变量的话就不占用某个内存空间,函数结束之后空间就不会被回收了么?

#8


引用 6 楼 sololie 的回复:
上面代码仓促说得不对,返回的地址不等于指针变量,不过大体意思就是这样了

我好像有点明白了,你那两个例子是说返回变量的地址,但是自定义的变量在函数结束之前内存已经被回收了,所以不对;
而我的函数只是将值返回了,跟内存并没有打交道。
不知道这样理解有没有偏差?

#9


函数的返回值保存在栈帧或寄存器中,函数返回前 返回值被保存在栈帧或寄存器中,函数内的局部变量都将被自动销毁(new的除外,new在堆中创建)。
int、float....struct这些是值类型,值类型就直接复制值,值就在寄存器中如同立即数,引用或指针就复制指针,引用或指针指向的东西的有效期得自己把握。

#10


怕俺自己误人子弟,还是等高人给你指点吧

#11


引用 10 楼 sololie 的回复:
怕俺自己误人子弟,还是等高人给你指点吧

我觉得你解释的很清楚,我大概懂了,谢谢你 千万不能返回局部变量的引用????