什么是内存泄漏
简单来说,内存泄漏就是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
对于C/C++程序猿更要注意这个问题,因为C/C++程序中,动态申请的内存都需要程序猿自己手动释放。不像Java有垃圾回收机制,所以作为一名C/C++程序猿,了解几个内存泄漏检查工具还是很有必要的。
Windows下的内存泄漏检测工具
Visual Studio 2013自带的内存泄漏检测工具
#include <iostream>
using namespace std;
int main(){
int* ptr = new int[10];
system("pause");
return 0;
}
在main函数的最后一行加上一句_CrtDumpMemoryLeaks();
调试程序,结束后查看输出。注意要包含头文件#include <crtdbg.h>
。注意:_CrtDumpMemoryLeaks();
要加在return 0;
之前。
#include <iostream>
#include <crtdbg.h>
using namespace std;
int main(){
int* ptr = new int[10];
_CrtDumpMemoryLeaks();
system("pause");
return 0;
}
记住方括号中的编号148。我们在main()函数第一行加上_CrtSetBreakAlloc(148);
意思就是在申请148这块内存的位置中断。
#include <iostream>
#include <crtdbg.h>
using namespace std;
int main(){
_CrtSetBreakAlloc(148);
int* ptr = new int[10];
_CrtDumpMemoryLeaks();
system("pause");
return 0;
}
然后调试程序。程序中断时,查看调用堆栈。
自带的内存泄漏检查工具使用太过麻烦,下面介绍一种更好用的工具。
VLD(Visual Leak Detector)内存泄漏库
VLD使用起来非常简单,只需在要测的源文件中加入#include <vld.h>
头文件。然后运行程序就可以发现内存问题。
首先下载安装VLD。
下载链接提取码:h9f6
全部勾选即可,然后无脑next即可,直到finish。和以前的版本不一样,VLD会将自己配置在VS上,所以我们现在不用再对自己的项目进行对VLD头文件和library库文件的添加配置。打开项目属性就可以看到。
我们需要用的时候只需要添加头文件#include <vld.h>
就可以。
#include <iostream>
#include <vld.h>
using namespace std;
int main(){
int* ptr = new int[10];
system("pause");
return 0;
}
选择Debug模式,运行即可。
但是,我这里优点问题,这个程序是有内存泄漏的,理论上应该能检测出来,但是并没有(O(∩_∩)O哈哈~)有知道为什么的欢迎指点。
Linux下的内存泄漏检查工具
valgrind
安装:
[sss@aliyun test]$ sudo yum install valgrind
验证是否安装成功:
[sss@aliyun test]$ valgrind ls -l
==19705== Memcheck, a memory error detector
==19705== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==19705== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==19705== Command: ls -l
==19705==
total 8
-rw-rw-r-- 1 sss sss 84 May 26 08:59 class.cc
-rw-rw-r-- 1 sss sss 69 May 28 13:41 test.cc
==19705==
==19705== HEAP SUMMARY:
==19705== in use at exit: 19,417 bytes in 8 blocks
==19705== total heap usage: 202 allocs, 194 frees, 74,590 bytes allocated
==19705==
==19705== LEAK SUMMARY:
==19705== definitely lost: 0 bytes in 0 blocks
==19705== indirectly lost: 0 bytes in 0 blocks
==19705== possibly lost: 0 bytes in 0 blocks
==19705== still reachable: 19,417 bytes in 8 blocks
==19705== suppressed: 0 bytes in 0 blocks
==19705== Rerun with --leak-check=full to see details of leaked memory
==19705==
==19705== For counts of detected and suppressed errors, rerun with: -v
==19705== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
输入命令valgrind ls -l
出现上述信息,表示安装成功。
使用说明:
Valgrind工具包包含多个工具,如Memcheck、Cachegrind、Helgrind、Callgrind、Massif等等。
演示代码:
#include <iostream>
int main(){
int* ptr = new int;
return 0;
}
首先编译程序,注意加上-g选项,保留调试信息。
[sss@aliyun test]$ g++ -g test.cc -o test
valgrind直接工作于可执行文件上,因此在检查前不需要重新编译、链接和修改程序。
命令格式如下:
valgrind --tool=tool_name program_name
比如说,对ls -l命令做内存检查:
[sss@aliyun test]$ valgrind --tool=memcheck ls -l
下面是使用valgrind检测是否有内存泄漏:
[sss@aliyun test]$ valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./test
其中:
-
--leak-check=full
指的是完全检查内存泄漏。 -
--show-reachable=yes
是显示内存泄漏的地点。 -
--trace-children=yes
是跟入子进程。
当程序正常退出后,valgrind就会输出内存泄漏的信息。
Linux下还有很多内存泄漏检查工具,比如说:mtrace、dmalloc、Kmemleak等等。这里就不一一举例介绍了。感兴趣的可以自己去了解下。