CPP学习之——在哪里创建就在哪里释放(9.19)

一 概述

只要在堆中创建一块内存空间,就会返回一个指向该空间的指针,我们一定不要弄丢该指针,假如该指针丢失,那么该堆中空间就会成为一块不可访问的区域,也就是程序员们经常说的内存泄漏。

同样假如我们将存储在堆中的对象初始化给一个引用,那么当该对象被删除时,这个引用也就成了空引用,假如我们无意中使用了这个空引用的话,就会令程序出错。

二 原因分析

  • 这就是第17和18节中的程序所犯的错误,本节我们就来解决这些错误,我们可以在func()函数中创建堆中对象,然后在main函数中释该对象,但是第18节的程序告诉我们,这样也不安全,虽然我们也可以用指针来代替引用,但是假如我们无法确定指向堆中对象的指针是哪一个,是func()函数的p指针,还是main函数中接受堆中对象的r指针,那么我们就有可能将该指针删除两次,或者忘记删除指针

三 如何做

  • 这样为了避免指针混淆,我们必须:在哪里创建,就在哪里释放
  • 因此我们在main函数中创建一个堆中对象,然后按引用的方式传递到func()函数中,在func()函数中对该对象操作完毕后返回该对象,然后在main函数中释放该对象。这样就实现了在main函数中创建,在main函数中释放

四 代码及结果演示

4.1 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>
using namespace std;
class A
{
private:
int x;
public:
A(int i)
{
cout << "执行构造函数创建一个对象\n";
x = i;
}
A(const A &a)
{
x = a.x;
cout << "执行复制构造函数创建对象\n";
}
~A() {cout << "执行析构函数!\n";}
int get() const {return x;}
void set(int i){x=i;}
};
A& func(A&a)
{
cout << "跳转到func函数中!\n";
a.set(66);
return a;
}
int main()
{
A *p=new A(99);
func(*p);
cout<<p->get()<<endl;
delete p;
return 0;
}

4.2 输出结果

1
2
3
执行构造函数创建一个对象
跳转到func函数中!
66