Open zixie1991 opened 7 years ago
memcheck探测程序中内存管理存在的问题。它检查所有对内存的读/写操作,并截取所有的malloc/new/free/delete调用。因此memcheck工具能够探测到以下问题:
memcpy
常见的内存分配方式分三种:静态存储,栈上分配,堆上分配。全局变量属于静态存储,它们是在编译时就被分配了存储空间,函数内的局部变量属于栈上分配,而最灵活的内存使用方式当属堆上分配,也叫做内存动态分配了。常用的内存动态分配函数包括:malloc, alloc, realloc, new等,动态释放函数包括free, delete
一旦成功申请了动态内存,我们就需要自己对其进行内存管理,而这又是最容易犯错误的。常见的内存动态管理错误包括:
申请和释放不一致 申请和释放不匹配 释放后仍然读写
释放空指针不算重复释放
char *ptr = NULL; free(ptr);
valgrind不对静态数组(分配在栈上)进行边界检查。如果在程序中声明了一个数组:
int main() { char s[10]; s[10] = 'a'; return 0; }
valgrind则不会警告你,你可以把数组改为动态在堆上分配的数组,这样就可能进行边界检查了。这个方法好像有点得不偿失的感觉。
另:可以使用静态代码检测工具进行检测,如cppcheck
valgrind占用更多的内存——两倍于程序的正常使用量,如果你用valgrind来检测使用大量内存的程序就会遇到问题,它可能会用很长的时间来运行测试。valgrind不可能检测出你在程序中犯下的所有错误——如果你不检查缓冲区溢出(buffer overflow detected),Valgrind也不会告诉你代码写了它不应该写的内存。
valgrind检测内存泄露
memcheck
memcheck探测程序中内存管理存在的问题。它检查所有对内存的读/写操作,并截取所有的malloc/new/free/delete调用。因此memcheck工具能够探测到以下问题:
valgrind示例
使用未初始化的内存
内存读写越界
src和dst内存覆盖
memcpy
动态内存管理错误
常见的内存分配方式分三种:静态存储,栈上分配,堆上分配。全局变量属于静态存储,它们是在编译时就被分配了存储空间,函数内的局部变量属于栈上分配,而最灵活的内存使用方式当属堆上分配,也叫做内存动态分配了。常用的内存动态分配函数包括:malloc, alloc, realloc, new等,动态释放函数包括free, delete
一旦成功申请了动态内存,我们就需要自己对其进行内存管理,而这又是最容易犯错误的。常见的内存动态管理错误包括:
申请和释放不一致 申请和释放不匹配 释放后仍然读写
内存泄漏
非法写/读
无效指针
重复释放
释放空指针不算重复释放
valgrind的局限性
valgrind不对静态数组(分配在栈上)进行边界检查。如果在程序中声明了一个数组:
valgrind则不会警告你,你可以把数组改为动态在堆上分配的数组,这样就可能进行边界检查了。这个方法好像有点得不偿失的感觉。
另:可以使用静态代码检测工具进行检测,如cppcheck
小结
valgrind占用更多的内存——两倍于程序的正常使用量,如果你用valgrind来检测使用大量内存的程序就会遇到问题,它可能会用很长的时间来运行测试。valgrind不可能检测出你在程序中犯下的所有错误——如果你不检查缓冲区溢出(buffer overflow detected),Valgrind也不会告诉你代码写了它不应该写的内存。