2 caojunqi123like caojunqi123like 于 2015.07.03 12:44 提问

C++引用变量问题,函数中临时变量返回引用
c++

C++ primer plus第六版引用一节,说不能在函数中新建一个变量,并将其引用返回。道理我都懂,就是说函数调用完后,那部分临时内存会释放。可是为什么我自己写的下述代码不报错,反而能正常运行呢?

#include
using namespace std;

struct free_throws //此处定义一个结构体
{
int i;
};

const free_throws & clone2(free_throws & ft1, free_throws & ft2); //函数声明
int main()
{
free_throws ftt,ft1,ft2; //新建三个结构体
ft1 = { 6 };
ft2 = { 4 };
ftt = clone2(ft1,ft2); //|按道理这块应该崩溃,但没崩
cout << ftt.i;
return 0;
}
const free_throws & clone2(free_throws & ft1, free_throws & ft2)
{
free_throws newguy;

newguy.i = ft1.i + ft2.i;
return newguy;
}

8个回答

91program
91program   Ds   Rxr 2015.07.03 12:52

和你代码返回的变量有关,因为代码 return newguy; 返回的是 newguy 的数值,而不是 newguy 的地址。所以,不会出错。
书上所说:“并将其引用返回”,是指返回 newguy 的引用、或者 newguy 的地址时,会出现错误。

civdx
civdx   2015.07.03 13:04

其实 clone2 返回的引用所指向的内存已经是野(释放了)的,只是在释放后没有任何操作再次征用,所以该块内存值未改变,内存尽管是野的,但只要属于进程,read是不会崩溃的,然后你的ftt紧接着拷贝了一份内存,所以ftt也可安全使用,但如果你的ftt是引用类型或指针类型,后续对ftt的读取将得到随机的值。

oyljerry
oyljerry   Ds   Rxr 2015.07.03 13:03

因为你用了const做修饰,对于const引用,它会延长临时变量生命期,把它绑定到ftt 上,所以你后面可以继续访问。

u011547347
u011547347   2015.07.03 13:34

你可以先输出这个变量的值(记为A),既然是C++,那么支持变量的随时创建,那么在调用clone2后,你可以再创建几个变量并初始化,然后再输出A,值应该会改变
另外关于为何不回崩溃,栈空间是有限的,我想可能是由于没有超出栈的总空间范围吧,再者说,访问一个内存不一定会出错,出错发生在内存不允许访问(如地址 0 或者对一个只读的文件指针进行写)

BlueCloudMatrix
BlueCloudMatrix   2015.07.03 14:05

Effective C++ 第21条:在必须返回一个对象时,不要去尝试返回一个引用

sunjilonggood
sunjilonggood   2015.07.03 14:41

你这根本就是浅拷贝,与临时变量没毛点关系。
你试试free_throws& ftt3 = clone2(ftt1, ftt2);
看看会不会报错,即使不报错也会警告的

frank_20080215
frank_20080215   2015.07.03 14:45

函数调用完后,那部分临时内存会释放。 -- 释放的含义是这个空间随时可被其他代码使用。其里面的内容只有在被其他代码使用时覆盖。这叫临时,
计算机的内存不属于城管管理范围的。因为是C++,内存管理都要程序员管理的。Java等的垃圾处理机制就类似于城管,但没有城管那么积极。
如果不是临时内存,则类似于你有张房屋的产权证。当代码要空间时,不会占用那块区域。与现实生活中的区别是,现实生活中空间不够,按照水泥和钢筋的重量计算,如果后者的重量大于现有的,则启动拆迁工程,即使有产权证也没用。
“可是为什么我自己写的下述代码不报错,反而能正常运行呢?” -- 这是因为暂时没有后续代码要使用该空间,所以这块空间里的内容仍旧是原来的。一旦后续代码使用,则由后续代码来接管处理。

caojunqi123like
caojunqi123like 嘻嘻,谢谢啊,您的意思就是说,我这程序崩溃是迟早的事,现在不崩,以后早晚崩。
2 年多之前 回复
frank_20080215
frank_20080215   2015.07.03 15:50

有点差异:练习练习,不动代码。是没事的。
在实际工作,如果要修改代码,出错崩溃的几率很高罢了。

Csdn user default icon
上传中...
上传图片
插入图片