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

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