VS排查和定位内存泄漏

1、什么是内存泄漏?

内存泄漏指的是在程序里动态申请的内存在使用完后,没有进行释放,导致这部分内存没有被系统回收,久而久之,可能导致程序内存不断增大,系统内存不足……引发一系列灾难性后果;(关于程序申请内存分配方式,详见:内存分配方式)

2、零容忍

排除内存泄漏对于程序的稳健型特别重要,尤其是程序需要长时间、稳定地运行时。C++这类动态内存申请释放都是由程序员控制的语言,稍不注意,很有可能就会有未释放的内存。这类问题,虽然有的时候仅仅只是泄漏了几个字节,但是危害极大。因此,我们一般都是要做到:内存泄漏零容忍!!!

3、检查、定位内存泄漏

检查方法:

在main函数最后面一行,加上一句_CrtDumpMemoryLeaks()。调试程序,自然关闭程序让其退出(不要定制调试),查看输出:

Detected memory leaks!
Dumping objects ->
{453} normal block at 0x02432CA8, 868 bytes long.
 Data: <404303374       > 34 30 34 33 30 33 33 37 34 00 00 00 00 00 00 00 
{447} normal block at 0x024328B0, 868 bytes long.
 Data: <404303374       > 34 30 34 33 30 33 33 37 34 00 00 00 00 00 00 00 
{441} normal block at 0x024324B8, 868 bytes long.
 Data: <404303374       > 34 30 34 33 30 33 33 37 34 00 00 00 00 00 00 00 
{435} normal block at 0x024320C0, 868 bytes long.
 Data: <404303374       > 34 30 34 33 30 33 33 37 34 00 00 00 00 00 00 00 
{429} normal block at 0x02431CC8, 868 bytes long.
 Data: <404303374       > 34 30 34 33 30 33 33 37 34 00 00 00 00 00 00 00 
{212} normal block at 0x01E1BF30, 44 bytes long.
 Data: <`               > 60 B3 E1 01 CD CD CD CD CD CD CD CD CD CD CD CD 
{204} normal block at 0x01E1B2C8, 24 bytes long.
 Data: <                > C8 B2 E1 01 C8 B2 E1 01 C8 B2 E1 01 CD CD CD CD 
{138} normal block at 0x01E15680, 332 bytes long.
 Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
{137} normal block at 0x01E15628, 24 bytes long.
 Data: <(V  (V  (V      > 28 56 E1 01 28 56 E1 01 28 56 E1 01 CD CD CD CD 
Object dump complete.
程序“[4860] TradeServer.exe: 本机”已退出,返回值为 0 (0x0)。

 

取其中一条详细说明:{453} normal block at 0x02432CA8, 868 bytes long. 

被{}包围的453就是我们需要的内存泄漏定位值,868 bytes long就是说这个地方有868比特内存没有释放。

接下来,定位代码位置:

在main函数第一行加上:_CrtSetBreakAlloc(453); 意思就是在申请453这块内存的位置中断。然后调试程序,……程序中断了。查看调用堆栈

双击我们的代码调用的最后一个函数,这里是CDbQuery::UpdateDatas(),就定位到了申请内存的代码:

好了,我们总算知道是哪里出问题了,这块内存没有释放啊。改代码,修复好这个。然后继续…………,直到调试输出中没有normal block ,程序没有内存泄漏了。

记得加上头文件:#include <crtdbg.h>

最后要注意一点的,并不是所有normal block一定就有内存泄漏,当你的程序中有全局变量的时候,全局变量的释放示在main函数退出后,所以在main函数最后_CrtDumpMemoryLeaks()会认为全局申请的内存没有释放,造成内存泄漏的假象。如何规避呢?我通常是把全局变量声明成指针在main函数中new 在main函数中delete,然后再调用_CrtDumpMemoryLeaks(),这样就不会误判了。
————————————————
版权声明:本文为CSDN博主「疯狂-的-蜗牛」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mfcing/article/details/42673393

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章