您的位置:首页 > 编程语言 > C语言/C++

从检查内存泄露从而无比怀念C++

2011-09-08 09:01 169 查看
作者:gfree.wind@gmail.com博客:http://linuxfocus.blog.chinaunix.net
马上就要Release了,可是公司内部运行的盒子,却有两个进程出现了比较严重的内存泄露。先检查了Coverity的检测报告——Coverity是一个很不错的静态代码检测工具,只找到了一处真正的内存泄露。因为是公司线上使用的盒子,没有办法使用valgrind去检查,因为valgrind必然会降低性能,那么公司的网络就会出现问题。
唉,没办法,只能人工review代码了。通过pmap查看进程的内存分布,确认了不断增长的内存是堆上的。那么也就是malloc后,没有free。用了两天时间把所有malloc的代码都过了一遍。由于很多地方是嵌套好几层以后,malloc的内存,然后在外层释放的,所有检查起来还是比较困难。我开了几个SourceInsight,最终一共找到了7处严重的内存泄露——有一处与Coverity找到的相同。
大致有3种情况,造成了内存泄露:1. 调用sqlite的API。其中1个是申请某资源的句柄,另外一个是释放该句柄;造成内存泄露的原因是,连续调用了2次申请资源的API。——以我的猜想,估计是同事认为,第一个API是可以连续使用的,殊不知sqilte中并不会检测输入参数,进入该API后,会直接初始化参数,然后申请资源赋给该参数。也就说第一个资源的句柄完全丢失了;2. 自己定义的1对API,一个是申请内存,另外一个是释放内存。申请内存是为3个成员变量指针申请了内存,而释放时只释放了2个。——估计是加入新的feature时,只更新了初始化函数,会忘记了释放函数。3. 遗漏了释放句柄的代码。——纯粹是马虎。
当我花了2天时间去检查内存泄露问题,觉得这个事情仅仅是琐碎而已。如果在编码过程中,养成好的习惯,写了申请内存的代码,立刻就在后面加上释放的代码,就可以避免不少内存泄露。
更好的方法是,如果我们使用C++的话,大部分的内存泄露都可以避免了。资源使用类进行包装,析构时检测释放资源。其实是动态申请,通过使用智能指针来封装,也可以避免内存泄露。
虽然一直都说C++在性能上跟C还是有一些差距的。但是在大部分代码中,仍然可以把C++当成C来写,不使用其他的C++特性。只在内存,锁,文件句柄等资源上,进行类的包装,就可以避免遗漏资源的释放。
可是为什么我们不能这样干呢?本文出自 “prothes blog” 博客,请务必保留此出处http://prothesman.blog.51cto.com/8610862/1411724
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: