C++?內(nèi)存泄漏調(diào)試方式
C++和其他高級語言不同,需要自行管理內(nèi)存,項(xiàng)目大\調(diào)用多,容易內(nèi)存泄漏.內(nèi)存申請釋放使用malloc
/free
和new delete
兩種方式.
當(dāng)內(nèi)存報(bào)錯(cuò)彈出一個(gè)陌生的地址,我一臉懵逼,不清楚是哪個(gè)地方出的錯(cuò),特別是程序退出的時(shí)候報(bào)錯(cuò)更不好定位.可以使用第三方工具來定位解決,也可以自己想辦法解決.
我在做神經(jīng)網(wǎng)絡(luò)訓(xùn)練的時(shí)候碰到一個(gè)的BUG,發(fā)送完訓(xùn)練圖片之后直接提示使用了非法內(nèi)存.
HEAP[Test.exe]: HEAP: Free Heap block 0000015E950E4A60 modified at 0000015E950E4AA0 after it was freed.
代碼迭代了多次,部分功能沒有測試,也不清楚哪里出的問題.
聯(lián)想到內(nèi)存的申請釋放方式,申請和釋放總是配對的,申請的大小也是預(yù)先知道的.在內(nèi)存申請申請釋放的時(shí)候加上內(nèi)存地址打印,當(dāng)內(nèi)存泄漏報(bào)錯(cuò)的時(shí)候就可以定位出錯(cuò)內(nèi)存地址在哪個(gè)范圍.我加入了一個(gè)內(nèi)存打印函數(shù),把內(nèi)存地址范圍和時(shí)間都打印出來.
void DebugHeap(CString name, void * ptr,int size) { ?? ?long Time = GetCurrentTime(); ?? ?TRACE("========>heap name:%s,address [%p:%p],time:%d (ms)\n", name,ptr,(char *)ptr + size,Time); }
在程序中申請\釋放部分加入DebugHeap
static Neural * mThis; static FileInfo mFileInfo; Neural *Neural:: GetInstance(MainDlg * parent,DlgCommand * cmd) { ?? ?if (mThis == NULL) ?? ?{ ?? ??? ?mThis = new Neural(parent); ?? ??? ?mCmd = cmd; ?? ?} ?? ?return mThis; } ? void Neural:: ReleaseInstance() { ?? ?if (mThis != NULL) ?? ??? ?delete mThis; } ? Neural::Neural(MainDlg * parent) { ?? ?mFileInfo.mRcv = (unsigned char *)malloc(1024); ?? ?DebugHeap("flag1:alloc", mFileInfo.mRcv, 1024); } ? Neural::~Neural(void) { ?? ?bWork = FALSE; ?? ?DebugHeap("flag1:free ", mFileInfo.mRcv, 1024); ?? ?free(mFileInfo.mRcv); }
程序運(yùn)行中的日志:
==> ?ThreadRecvProc Start ==> ?ThreadInterrupt Start MainDlg::OnInitDialog() ========>heap name:flag1:alloc,address [0000015E95077CD0:0000015E950780D0],time:7870921 (ms) “Test.exe”(Win32): 已加載“C:\Windows\System32\clbcatq.dll”。無法查找或打開 PDB 文件。 “Test.exe”(Win32): 已加載“C:\Windows\System32\edputil.dll”。無法查找或打開 PDB 文件。 .... 線程 0x2a10 已退出,返回值為 0 (0x0)。 線程 0x2ae4 已退出,返回值為 0 (0x0)。 “Test.exe”(Win32): 已加載“C:\Windows\System32\mswsock.dll”。無法查找或打開 PDB 文件。 連接服務(wù)器成功! 線程 0x16c8 已退出,返回值為 96 (0x60)。 線程 0xa0c 已退出,返回值為 0 (0x0)。 “Test.exe”(Win32): 已加載“C:\Windows\System32\msctfuimanager.dll”。無法查找或打開 PDB 文件。 .... ========>heap name:flag1:alloc,address [0000015E951577D0:0000015E95157BD0],time:7885500 (ms) Ending:43707 ========>heap name:flag1:free ,address [0000015E951577D0:0000015E95157BD0],time:7885609 (ms) 線程 0x2f20 已退出,返回值為 0 (0x0)。 ========>heap name:flag1:alloc,address [0000015E950E4AA0:0000015E950E4EA0],time:7887265 (ms) analyse:3, D:\數(shù)據(jù)\FSSD\V5\target.csv ========>heap name:flag1:free ,address [0000015E950E4AA0:0000015E950E4EA0],time:7887296 (ms) 線程 0x2a00 已退出,返回值為 0 (0x0)。 線程 0xe84 已退出,返回值為 0 (0x0)。 HEAP[Test.exe]: HEAP: Free Heap block 0000015E950E4A60 modified at 0000015E950E4AA0 after it was freed Test.exe 已觸發(fā)了一個(gè)斷點(diǎn)。
- 第一次申請 [0000015E95077CD0:0000015E950780D0] 釋放失敗
- 第二次申請[0000015E951577D0:0000015E95157BD0] 釋放成功
- 第三次申請[0000015E950E4AA0:0000015E950E4EA0] 釋放成功
從報(bào)錯(cuò)的意思看是重復(fù)釋放內(nèi)存.0000015E950E4AA0
地址被重復(fù)釋放,這個(gè)地址剛好是第三次申請的地址.
看現(xiàn)象是第一次申請的地址被改動(dòng)了,查看這部分代碼分析原因.
按照我預(yù)想在構(gòu)造函數(shù)申請內(nèi)存,析構(gòu)函數(shù)釋放內(nèi)存,是能配對.代碼里加入單例模式并且使用了一個(gè)全局變量mFileInfo,隨著構(gòu)造函數(shù)調(diào)用會(huì)不斷改變.我預(yù)想是這個(gè)類只能單例使用,由于歷史原因,部分代碼并沒有使用單例模式.單例中的申請的地址位置被改動(dòng)了,所以沒辦法正確釋放.統(tǒng)一使用單例模式,這個(gè)問題解決了.
C++出現(xiàn)內(nèi)存錯(cuò)誤時(shí)候,把申請/釋放的地址打印出來能更快更準(zhǔn)確的定位到問題.
到此這篇關(guān)于C++ 內(nèi)存泄漏調(diào)試方式的文章就介紹到這了,更多相關(guān)C++ 內(nèi)存泄漏內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt QStandardItemModel用法小結(jié)
QStandardItemModel可用作標(biāo)準(zhǔn)Qt數(shù)據(jù)類型的存儲(chǔ)庫,本文主要介紹了Qt QStandardItemModel用法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12C++設(shè)計(jì)模式之組合模式(Composite)
這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之組合模式Composite,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04OpenCV獲取鼠標(biāo)左鍵點(diǎn)擊位置圖像的像素值
這篇文章主要為大家詳細(xì)介紹了OpenCV獲取鼠標(biāo)左鍵點(diǎn)擊位置圖像的像素值,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01一篇文章帶你用C語言玩轉(zhuǎn)結(jié)構(gòu)體
本文主要介紹C語言 結(jié)構(gòu)體的知識,學(xué)習(xí)C語言肯定需要學(xué)習(xí)結(jié)構(gòu)體,這里詳細(xì)說明了結(jié)構(gòu)體并附示例代碼,供大家參考學(xué)習(xí),有需要的小伙伴可以參考下2021-09-09詳解C語言編程中的函數(shù)指針以及函數(shù)回調(diào)
這篇文章主要介紹了C語言編程中的函數(shù)指針以及函數(shù)回調(diào),函數(shù)回調(diào)實(shí)際上就是讓函數(shù)指針作函數(shù)參數(shù)、調(diào)用時(shí)傳入函數(shù)地址,需要的朋友可以參考下2016-04-04