前言,内存管理常见的内存错误
1.内存泄漏:内存没有被释放,导致内存浪费。解决方案可以采用以下方法:
手动管理内存并调用free()释放不再使用的内存;
使用智能指针等自动内存管理机制;
使用内存泄漏检测工具定位和修复内存泄漏问题。
2.内存溢出:访问的内存超过申请内存大小。解决方案可以采用以下方法:
程序设计时充分考虑内存使用情况,合理地规划内存分配;
使用内存监控工具或者操作系统提供的性能工具,监测和分析程序内存使用情况;
优化算法或数据结构,减少内存占用。
3.野指针:指针指向了已经被释放的内存空间,或者指针未被初始化就被使用。解决方案可以采用以下方法:
对指针变量进行初始化;
在指针使用之前,检查其是否为空或者指向的内存是否被释放;
使用nullptr代替NULL,避免空指针问题;
使用智能指针等自动内存管理机制,避免手动释放内存的错误。
一,Valgrind
Valgrind 是一个运行时诊断工具,它可以监视 一个指定程序的活动并通知你在你的代码中可能存在的各种各样的内存管理问题。它类似于老式的 Electric Fence 工具(该工具将标准的内存分配函数替换为自己的函数以提高诊断能力),但被认为更容易使用并且在多个方面都提供了更丰富的功能 —— 而且现在大多 数主流 Linux 发行版都提供了该工具,所以在你的系统中使用它不需要花费太多时间,你只需安装它的软件包即可。
1.MemCheck基本原理
官方
memcheck实现了一个仿真的CPU,被监控的程序被这个仿真CPU解释执行,从而有机会在所有的内存读写指令发生的时候,检测地址的合法性和读操作的合法性。具体的花通过2张表:
①合法地址表:Valid-address (A) bits
当前所有可以合法读写(已分配)的地址在其中有对应的表项。该表通过以下措施维护
全局数据(data, bss section)–在程序启动的时候标记为合法地址
局部变量–监控sp(stack pointer)的变化,动态维护
动态分配的内存–截获 分配/释放 内存的调用:malloc, calloc, realloc, valloc, memalign, free, new, new[], delete and delete[]
系统调用–截获mmap映射的地址
二,如何知道某内存是否已经被赋值?
②合法值表(Valid-value (V) bits),指示对应的bit是否已经被赋值。因为虚拟CPU可以捕获所有对内存的写指令,所以这张表很容易维护。
2.MemCheck局限:
memcheck无法检测global和stack上的内存溢出,因为溢出的地方也在Valid-address (A) bits中。这是由memcheck 的工作原理决定的
3.MemCheck错误类型:
①Illegal read / Illegal write errors(非法读写错误)
读写超出堆申请范围,堆:√ 栈:× 全局变量:×
②Use of uninitialised values [值在初始化前使用]
这个错误很奇怪,堆:√ 栈:× 全局变量:×
③Illegal frees [非法释放内存]
这个只能是堆
④Mismatched free() / delete / delete [][申请释放不匹配]
这个只能是堆,malloc, calloc, realloc, valloc or memalign=> free
new =>delete
⑤Overlapping source and destination blocks [源头和目标块重叠]
C库中一些具有拷贝功能的函数,如memcpy(), strcpy(), strncpy(), strcat(), strncat(),他们将数据从一个内存块中拷贝至另一个中。源头和目标内存块不允许有重叠, Memcheck 可以检查这种错误
⑥Memory leak detection
只能用于堆,
根据 –leak-check 设置值,显示对应的内存泄露具体类型.