C++动态分配后的内存释放

最近在用C++写项目时遇到的一些动态分配上的易错点,所以写这篇博客来记录下。下面我会列举一些问题作为例子来总结一下动态分配的易错点,如有不对,欢迎指正。

我们经常会在一个函数中对指针进行动态分配。动态分配伴随着释放,不及时释放分配的内存会造成内存泄漏,那么我们应该什么时候在哪里释放已经分配的内存呢?

作用域结束后释放

常见的情况是在函数中动态分配了一个指针,我们在函数作用域结束时释放该指针,防止内存泄漏。下面是一个在作用域结束后释放的例子

void func()
{
	int* p = new(int);
	
	int a = 1, b = 2;	

	delete p;
	p = NULL;
	return;
}

我们在函数 func() 中申请了一个指针 p,并为它动态分配内存空间,我们在函数作用域结束前将分配给它的内存释放掉。

看起来很简单,好的,我们来看下一个例子:

void func_mutiBacks(int a , int b)
{
	int *p = new(int);
    if (b - a)
    {
    	return;
    }
	
	delete p;		
	p = NULL;
	return;
}

func_mutiBacks(1, 1);	// 函数没有走到最后,提前返回,指针p没有释放,内存泄漏

函数 func_mutiBacks() 是一个多出口函数,即拥有多个返回点。 func_mutiBacks(1, 1) 函数会提前返回,此时指针p没有释放,内存泄露。
对于有多个出口的函数,我们在return之前释放指针内存,修改后的代码如下:

void func_mutiBacks(int a , int b)
{
	int *p = new(int);
    if (b - a == 0)
    {// 在return前释放指针内存
    	delete p;		
		p = NULL;
    	return;
    }
	
	delete p;		
	p = NULL;
	return;
}
func_mutiBacks(1, 1);

此时指针p正确被释放,不会造成内存泄漏。

利用析构函数释放指针内存

通过刚才的两个例子可以看到,一个函数在有多个出口的情况下,我们必须对每个出口都加一道“门”,必须在每个return前写一次释放。这样未免也太麻烦了!那有没有什么方法可以让我们不用思考这么多直接用呢?

我们知道析构函数会在类对象结束时自动调用并释放掉对象的内存。 所以我们在写项目的时候,可以将指针放在一个类中,在析构函数里释放申请的指针内存。 这样就不用考虑释放不及时造成内存泄露了。下面是一个利用析构函数释放指针内存的一个例子:

// 类CPoint
class CPoint
{
public:
    CPoint();
    ~CPoint();

    int* get(); //  指针 m_point*
private:
    int* m_point;
};

CPoint::CPoint():m_point(NULL)
{
    m_point = new int;
}
CPoint::~CPoint()
{
    delete m_point;
    m_point = NULL;     // 销毁后要指向空
}
int* CPoint::get()
{// 返回指针
    return m_point;
}

void func_mutiBacks(int a , int b)
{
	CPoint p;
    if (b - a == 0)
    {
    	return;
    }
    int c = 1;
	*(p.get()) = c;
	std::cout << *(p.get()) << std::endl;	// 输出1
	return;
}
func_mutiBacks(1, 2);

此时指针 m_point会随着 对象p 生命周期的结束而自动释放内存,不会出现内存泄露的问题。
这只是一个很简单的例子,例子中我们也没用指针做其他事情,所以可能有人会觉得这样十分麻烦,但如果我们要频繁的动态分配一个指针,那还是建议封装到类里比较好。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值