在写大型C/C++工程时不免会发生内存泄漏现象,系统编程中一个重要的方面就是有效地处理与内存相关的问题。你的工做越接近系统,你就须要面对越多的内存问题。有时这些问题很是琐碎,而更多时候它会演变成一个调试内存问题的恶梦。 常见的内存问题一共七种:1. 动态内存泄露;2. 资源泄露,好比文件指针不关闭;3. 动态内存越界;4.数组内存越界;5.动态内存double free;6.使用野指针,即未初始化的指针;7.释放野指针,即未初始化的指针。 内存问题很是难定位,对于小工程来讲,简单去检查代码中new和delete的匹配对数就基本能定位到问题,可是一旦代码量上升到以万单位时,仅靠肉眼检查来定位问题那就很是困难了,因此咱们须要利用工具帮助咱们找出问题所在。在Linux系统下内存检测工具首推Valgrind,一款很是好用的开源内存管理框架。Valgrind实际上是一个工具集,内存错误检测只是它众多功能的一个,但咱们用得最多的功能正是它——memcheck。 该工具能够检测下列与内存相关的问题 : 未释放内存的使用 对释放后内存的读/写 对已分配内存块尾部的读/写 内存泄露 不匹配的使用malloc/new/new[] 和 free/delete/delete[] 重复释放内存 首先安装Valgrind很是简单: //valgrind下载:http://valgrind.org/downloads/valgrind-3.12.0.tar.bz2valgrind安装:1. tar -jxvf valgrind-3.12.0.tar.bz22. cd valgrind-3.12.03. ./configure4. make5. sudo make install 下面开始讲解Valgrind的应用场景。 注意: 下面讨论的全部测试代码都应该使用gcc/g++而且加上-g选项。 1. 使用未初始化的内存(使用野指针) 这里咱们定义了一个指针p,但并未给他开辟空间,即他是一个野指针,但咱们却使用它了。 Valgrind检测出咱们程序使用了未初始化的变量,但并未检测出内存泄漏。 2.在内存被释放后进行读/写(使用野指针) p所指向的内存被释放了,p变成了野指针,可是咱们却继续使用这片内存。 Valgrind检测出咱们使用了已经free掉的内存,并给出这片内存是哪里分配哪里释放的。 3.从已分配内存块的尾部进行读/写(动态内存越界) 咱们动态地分配了一段数组,但咱们在访问个数组时发生了越界读写,程序crash掉。 Valgrind检测出越界的位置。 注意:Valgrind不检查静态分配数组的使用状况!因此对静态分配的数组,Valgrind表示无能为力!好比下面的例子,程序crash掉,咱们殊不知道为何。 4.内存泄漏 内存泄漏的缘由在于没有成对地使用malloc/free和new/delete,好比下面的例子。 Valgrind会给出程序中malloc和free的出现次数以判断是否发生内存泄漏,好比对上面的程序运行memcheck,Valgrind的记录显示上面的程序用了1次malloc,却调用了0次free,明显发生了内存泄漏! 上面提示了咱们可使用--leak-check=full进一步获取内存泄漏的信息,好比malloc和free的具体行号。 5. 不匹配地使用malloc/new/new[] 和 free/delete/delete[] 正常使用new/delete和malloc/free是这样子的: 而不匹配地使用malloc/new/new[] 和 free/delete/delete[]则会被提示mismacth: 6.两次释放内存 double free的状况一样是根据malloc/free的匹配对数来体现的,好比free多了一次,Valgrind也会提示。 固然,Valgrind也不是万能的。Valgrind也有没法找到问题的时候,有些问题只能经过不断的review代码找到了症结。发现问题,解决问题,毕竟是末流。最好的方法,就是不引入内存问题。这能够经过良好的代码风格和设计来实现的。 文末也给你们,分享主要有C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK技术,面试技巧方面的资料技术讨论。 感兴趣的朋友能够加群:812855908