C/C++查找内存泄露的方法
文章目录
- C/C++查找内存泄露的方法
-
- 工具概括
- 一、利用valgrind的memcheck工具动态检测内存泄露
-
- 检测内容:
- 检测方法:
- 检测结果:
- 二、利用cppcheck工具静态检测内存泄露
-
- 检测内容:
- 检测方法:
- 检测结果:
- 三、利用valgrind的massif工具动态检测内存泄露
-
- 检测内容:
- 检测方法:
- 检测结果:
项目实际经验总结!!!靠以下几种工具查找内存泄露,快速且准确!大家可以看前面的概括,选择适合自己情况的工具,来查找内存泄露。希望大家的代码都能无bug、完美运行!
工具概括
1、memcheck:适合检测程序运行短时间内出现的内存泄露;
2、cppcheck:适合检测一些我们可能忽略的代码错误。在代码中,有一些情况在程序运行中很少会发生,从而容易疏忽这些情况下的内存管理,而导致内存泄露,可以由此工具检测出来;
3、massif:适合检测程序运行长时间内出现的内存泄露。随着运行时间变长,有些分配的内存一直不被释放,或者还在逐渐申请新的内存,导致程序占用的内存随着运行时间逐渐增长,这时我们就需要好好注意这部分代码;
一、利用valgrind的memcheck工具动态检测内存泄露
检测内容:
· 使用未初始化的内存(Use of uninitialised memory)
· 使用已经释放了的内存(Reading/writing memory after it has been free’d)
· 使用超过malloc分配的内存空间(Reading/writing off the end of malloc’d blocks)
· 对堆栈的非法访问(Reading/writing inappropriate areas on the stack)
· 申请的空间是否有释放(Memory leaks – where pointers to malloc’d blocks are lost forever)
· malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])
· src和dst的重叠(Overlapping src and dst pointers in memcpy() and related functions)
检测方法:
- a、安装valgrind
//1.进入网站下载源码
http://valgrind.org/downloads/current.html#current
//2.解压,然后进入解压后的目录
tar -jxf valgrind-3.13.0.tar.bz2
//3.安装
./configure --prefix=/home/valgrind(安装路径)
make
make install
//4.查看版本
valgrind --version
- b、使用:
valgrind --tool=memcheck --leak-check=full --trace-children=yes --show-reachable=yes --log-file=error.log ./pss_client
1、–tool=memcheck:选择memcheck工具来对程序进行内存检查;
2、–leak-check=full:完全检查内存泄露;
3、–trace-children=yes:是否对子进程进行跟踪;
4、 --show-reachable=yes:定位内存泄漏位置(具体到哪个函数的哪一行)
5、–log-file=error.log:将检测到的内存问题保存到error.log文件当中;
6、./pss_client:运行我们的程序;
检测结果:
- 使用该工具并没有检测出我们的程序在整个运行过程存在内存泄露:
==14368==
==14368== HEAP SUMMARY:
==14368== in use at exit: 0 bytes in 0 blocks
==14368== total heap usage: 1,137 allocs, 1,137 frees, 5,603,265 bytes allocated
==14368==
==14368== All heap blocks were freed -- no leaks are possible
==14368==
==14368== For counts of detected and suppressed errors, rerun with: -v
==14368== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
二、利用cppcheck工具静态检测内存泄露
检测内容:
- error:出现的错误
- warning:为了预防bug防御性编程建议信息;
- style:编码格式问题(没有使用的函数、多余的代码等);
- portablity:移植性警告。该部分如果移植到其他平台上,可能出现兼容性问题;
- performance:建议优化该部分代码的性能;
- information:一些有趣的信息,可以忽略不看的;
检测方法:
- a、安装cppcheck
//1.进入网站下载源码
https://sourceforge.net/projects/cppcheck/
//2.解压,然后进入解压后的目录
tar -zxvf cppcheck-1.8.0.tar.gz
//3.安装
make
sudo make install
//4.查看版本
cppcheck --version
- b、使用:
cppcheck --xml-version=2 --enable=all /src 2> error.log
1、–xml-version=2:将检测结果以xml格式输出;
2、–enable=all:检测all是检查上述检测内容中的所有;默认情况下检测error,也可以检测warning/style等,
3、/src:检测src目录下的所有文件,也可以检测单个文件,如:main.c
4、2> error.log:将检测结果保存到error.log文件当中;
检测结果:
- 该工具检测出,在一些出错情况下,直接return了,没有对此前malloc/calloc的内存进行释放;
<error id="memleak" severity="error" msg="Memory leak: state" verbose="Memory leak: state" cwe="401">
<location file="pss_event_epoll.c" line="33"/>
</error>
- 如下列代码,state可能没被释放,而导致内存泄露:
pss_event_api_state_t *state = (pss_event_api_state_t *)calloc(1, sizeof(pss_event_api_state_t));
if (!state) {
PSS_LOGE("epoll api state error,:%s \n", strerror(errno));
return -1;
}
state->events = (struct epoll_event *)calloc(1, sizeof(struct epoll_event) * event_loop->set_size);
if (!state->events) {
PSS_LOGE("epoll api state event error,:%s \n", strerror(errno));
return -1; //如在此处return ,前面calloc的state没有free
}
三、利用valgrind的massif工具动态检测内存泄露
检测内容:
- massif是一个堆分析器,它统计程序使用的堆内存大小(由malloc等函数分配的内存;
- 堆分析可以帮助减少程序使用的内存。如果分配的内存还没有释放并且指针也在,这种情况对于Memcheck(内存泄漏检查器)来说不算错误。但是随着时间内存增加,这也算内存泄漏,Massif可以帮助识别这些泄漏;
- 重要的是,Massif不仅会报告程序正在使用多少堆内存,还会提供非常详细的信息,来指明这些内存是由程序中哪部分分配的;
检测方法:
- a、安装valgrind
//1.进入网站下载源码
http://valgrind.org/downloads/current.html#current
//2.解压,然后进入解压后的目录
tar -jxf valgrind-3.13.0.tar.bz2
//3.安装
./configure --prefix=/home/valgrind(安装路径)
make
make install
//4.查看版本
valgrind --version
- b、使用:
valgrind --tool=massif --time-unit=B --detailed-freq=1 ./pss client
1、–tool=massif:选择memcheck工具来记录程序运行过程中的堆内存变化;
2、–time-unit=B:快照采集时间,B的意思是以字节为单位来记录堆内存的变化;
3、–detailed-freq=1:设置详细快照的频率,当设置为1时,每个快照都被记录成详细的;
检测结果:
- 当程序运行停止后,会生成一个massif.out.29296文件(29296是程序的PID);
- 使用massif-visualizer工具来查看此文件:
1.安装massif-visualizer
sudo apt-get install massif-visualizer
2.启动
massif-visualizer
3.启动之后,选择程序运行生成的massif.out.29296文件打开,就能看到程序运行时的堆内存使用情况了;
- 大家可以参考该文章,教你如何看懂massif显示出来的内存使用情况 堆问题分析的利器——valgraind的massif