从汇编的眼光看C++(之delete内存泄露)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


    有过C语言编程的朋友大多知道,如果在malloc内存之后不及时free掉内存,那么很有可能会造成内存泄露的。那么在C++上面,是不是也存在这样的问题呢?结果是C++上面同样也存在内存泄露的危险。这个危险就是如果new后面不能delete的话,也会造成内存的泄露。还有不清楚的朋友可以看看下面的示例:

class test
{
	int data;
public:
	test(int value):data(value) {}
	~test() {};
};

void process()
{
	test* t = new test(0);

	if(/* some errors happens */)
	{
		return;
	}

	delete t;
	return;
}
    上面的代码在一定程度上说明了问题。其实上面这段代码在函数返回的时候已经考虑到了内存删除的问题,但是关键是如果在error发生的时候,没有及时处理的话也会造成内存泄露的。那么有没有什么好的方法呢?大家可以看看C++有没有什么性质可以保证函数在结束的时候可以自动完成资源的释放。对,那就是析构函数。所以,一般的话我们可以添加一个额外的类定义。

class auto_point
{
	test* t;
public:
	auto_point(test* p) : t(p) {}
	~auto_point() { if(t) delete t;}
};
    但是,原来我们的好多操作都是按照指针进行的,那么怎么把类转变成指针呢?那就只有使用算术符重载了。

class auto_point
{
	test* t;
public:
	auto_point(test* p) : t(p) {}
	~auto_point() { if(t) delete t;}
	test* operator->() { return t;}
	const test& operator* () {return *t;}
};

    那么有了这样的一个定义之后,我们应该怎么使用呢?大家可以看看下面的函数调用:

22:       auto_point p(new test(0));
004010AD   push        4
004010AF   call        operator new (00401300)
004010B4   add         esp,4
004010B7   mov         dword ptr [ebp-18h],eax
004010BA   mov         dword ptr [ebp-4],0
004010C1   cmp         dword ptr [ebp-18h],0
004010C5   je          process+56h (004010d6)
004010C7   push        0
004010C9   mov         ecx,dword ptr [ebp-18h]
004010CC   call        @ILT+80(test::test) (00401055)
004010D1   mov         dword ptr [ebp-1Ch],eax
004010D4   jmp         process+5Dh (004010dd)
004010D6   mov         dword ptr [ebp-1Ch],0
004010DD   mov         eax,dword ptr [ebp-1Ch]
004010E0   mov         dword ptr [ebp-14h],eax
004010E3   mov         dword ptr [ebp-4],0FFFFFFFFh
004010EA   mov         ecx,dword ptr [ebp-14h]
004010ED   push        ecx
004010EE   lea         ecx,[ebp-10h]
004010F1   call        @ILT+65(auto_point::auto_point) (00401046)
004010F6   mov         dword ptr [ebp-4],1
23:       if(1/* some errors happens */)
004010FD   mov         edx,1
00401102   test        edx,edx
00401104   je          process+97h (00401117)
24:       {
25:           return;
00401106   mov         dword ptr [ebp-4],0FFFFFFFFh
0040110D   lea         ecx,[ebp-10h]
00401110   call        @ILT+75(auto_point::~auto_point) (00401050)
00401115   jmp         process+0A6h (00401126)
26:       }
27:
28:       return;
00401117   mov         dword ptr [ebp-4],0FFFFFFFFh
0040111E   lea         ecx,[ebp-10h]
00401121   call        @ILT+75(auto_point::~auto_point) (00401050)
29:   }
    大家可以从上面的代码看得很清楚,不管代码在什么时候退出,函数都会利用类的基本特性,自动调用类的析构函数,那么进而内存就会得到释放,不会发生内存泄露的问题。但是我们发现上面的解决方案也有不足的地方,就是每一个类都需要额外定义一个额外的定义类。那么有没有什么办法解决这一问题呢?那就是模板了。

template <typename type>
class auto_point
{
	type* t;
public:
	auto_point(type* p) : t(p) {}
	~auto_point() { if(t) delete t;}
	test* operator->() { return t;}
	const test& operator* () {return *t;}
};
    如果我们的类型不是特定的,那么我们只需要在使用的时候按照特定的类型输入即可。



【预告: 下面的一篇博客会介绍类成员指针拷贝的问题】


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式-老费

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值