c/c++内存问题修复,内存使用剖析

c/c++能管理内存资源,能通过指针直接访问内存。c/c++的内存处理有很高的自由度、可控度和性能,但是也伴随着高昂的代价,即内存访问频繁的发生bug。

最常见的内存访问bug有内存泄漏(memory leak),内存管理的错误使用(incorrect use of memory management),缓冲区溢出(buffer overrun)和读取未初始化的内存(reading unnitialized memory)。

内存泄漏:在运行时分配,但当程序不再需要它时未释放的数据结构。如果内存泄漏频繁发生或很大,那么计算机所有可用主内存都将被耗尽。程序首先会变慢,因为计算机开始将页面转换为虚拟内存,最后以内存不足(out of memory)告终。

内存管理的错误使用:涉及一大类bug,例如多次释放一个内存块,在释放一个内存块之后又访问它,或释放一个从未分配的内存块。此类错误还包括,使用delete而不是delete[]来取消数组的分配,以及将malloc()与delete混用,或者将new与free()混用。

缓冲区溢出:在已分配内存外部的内存被改写或破坏。很多地方都可能发生缓冲区溢出,包括全局变量、栈上的局部变量,以及通过内存管理在堆上分配的动态变量。内存破坏的一个不良后果是,在改写内存的那条语句中看不到BUG。只有以后程序中另一条语句访问这个内存位置时,bug才会显露。由于内存位置有一个非法值,所以程序可能会产生多种错误行为,例如,程序可能会产生多种错误结果,或如果非法值在一个指针中,则程序将尝试访问被保护的内存并导致崩溃。如果函数指针变量被改写,则程序会跳转,并将数据当作程序代码来执行。关键是导致内存破坏的语句与触发可见bug的语句之间并没有明确的关系。

读取未初始化的内存:内存分配函数malloc()和操作符new不会初始化或清除已分配的内存块。未初始化的变量将包含无法预料的值。

有效的内存调试器,purify和valgrind等

当程序退出,Purify会查找泄漏的内存并给出未释放的内存报告.

Purify将内存分为三个状态,每个状态都会统计内存块的数量和大小.

Leaked memory

没有指针指向这块内存

Potentially Leaked memory

没有指针指向这块内存的头部,但是有指针指向这块内存的内部.

Memory in use

有指针指向的内存块(不存在泄漏的情况)

NOTE: 若运行的是一个需要长期不退出的程序,可以在程序尚在运行时,通过单击菜单栏中的`New Leaks tool`按钮来产生内存泄漏的情况报告.

参考链接:

https://blog.csdn.net/lujun9972/article/details/46003017

https://blog.csdn.net/haoel/article/details/2904

https://blog.csdn.net/destina/article/details/6198443

猜你喜欢

转载自blog.csdn.net/Fan0920/article/details/113784200