CPP学习之——引用一个按值返回的堆中对象(9.17)
一 概述
借用上一节课的代码。本节课讲的也是一种比较常见的错误 :引用一个返回的堆中对象引起的错误
二 代码及结果输出
2.1 代码
1 | #include<iostream> |
3.2 结果及现象
- 程序异常
3.3 代码说明
- 输出结果只执行了一次析构函数:p指针被删除了,它所指向的空间还存在。该空间的地址只有p保存着,而p找不到了,所以我们无法找到该空间。由于无法找到该空间,所以无法对其进行释放,结果造成了内存泄漏
- 由于引用会延长临时变量的生命,所以当main函数结束时,由复制构造函数创建的堆中对象的副本方才被销毁,所以调用析构函数来销毁该对象占用的内存,由于堆中对象无法找到,无法对其占用的内存进行释放,所以只调用了一次析构函数,这个析构函数销毁的是堆中对象的副本。
- 由于返回的是堆中对象的副本,这个副本是调用复制构造函数创建的。所以这个副本保存在栈中,而不是堆中。我们知道存放在栈中的数据都是由系统自动释放,而delete运算符删除的是堆中空间,而不是栈中空间,所以导致了错误
- 另外需要再次强调的是,指向堆中空间的p指针由于是个局部变量,因此在func函数返回时,它被系统自动释放了,然后由于它所指向的堆中空间必须使用delete运算符才能被删除,因此该空间成了不可访问的区域,结果导致了内存泄漏