最近剛換工作,還在試用期,分配給我的也都是些零碎的任務。
前陣子領導扔給我乙個小專案,這個專案底層使用c++編寫的3d渲染引擎,然後用cli包裝了一下,提供給上層的c#呼叫。這個專案存在比較嚴重的記憶體洩漏問題,由於目前公司寫c++的人寥寥無幾,寫c#的又不太懂如何檢測c++的記憶體洩漏,領導就把這個小任務扔給了我。
1.vld (visual leak detector)
vld 介紹
vld的使用非常簡單,只需要在c++專案的任意乙個參與編譯的cpp檔案中引用vld.h標頭檔案
然後在debug模式下執行程式,當程式退出時,在除錯視窗就會列印出產生的記憶體洩漏
洩漏資訊中可以定位到具體的洩漏行,幷包括詳細的堆疊呼叫。我用vs2017也試了一下,雖然也能檢測到洩漏,但不能定位到具體行,網上有一些所謂的黑科技可以解決,大致就是把vs2017安裝目錄下的
dbghelp.dll覆蓋到vld的安裝目錄下,讀者可以自己試一下。
2.crt(c執行時庫)
crt的使用不需要引用第三方標頭檔案或庫,在程式中包含如下**
然後在需要檢測洩漏的地方呼叫_crtdumpmemoryleaks(),debug模式下執行程式
如果希望在程式退出時自動列印所有的記憶體洩漏資訊,需要在程式啟動時呼叫_crtsetdbgflag(_crtdbg_alloc_mem_df | _crtdbg_leak_check_df)
這樣在程式退出的時候也會列印如上的洩漏資訊,並定位到行號。
但是如果只是加入上面的**,我們只有使用malloc造成的記憶體洩漏才能定位到具體行號,但是在c++中大多數情況下我們使用new動態分配記憶體,為了能夠檢測到使用new時候的洩漏位置,需要加上如下**
即對new操作符進行了重定義,這樣在程式中我們使用new的時候,debug模式下會用到重定義後的版本
這樣即可列印出具體的記憶體洩漏行號。
3.deleaker(可以檢測c#中的記憶體洩漏) 官網
deleaker有兩種執行模式,託管模式和.net模式,檢測c++的時候使用託管模式,在deleaker window中啟用deleaker
程式執行結束會在window中列出洩漏的位置
由於我的deleaker已經過了試用期,所有看不到具體的行號...
deleaker可以設定檢測的具體的洩漏型別,deleaker->options->settings->general settings->allocation types
deleaker比較好用的乙個功能是快照
可以在程式執行過程中記錄當前程式的記憶體快照,隔一段時間後再次記錄快照,然後將這兩個快照進行比較,記憶體洩漏問題就比較容易定位了!
tips:在使用deleaker的過程中遇到了乙個問題,由於我這個專案是用cli包裝c++後供c#呼叫,主程式是c#的,除錯c#程式時記錄快照特別慢...我嘗試和deleaker的開發者進行了溝通,對方也做了些改進,給了我幾個改進後的版本,雖然速度有所提高,但還是有些慢,最後也就不了了之了。deleaker單獨測試乙個純c++或者純c#程式時,快照的速度還是相當滿意的。
以上就是三種記憶體洩漏檢測方式,讀者可以根據自己的需求選擇合適的工具。
C C 記憶體洩漏檢查之經驗
c程式中最可怕的事情就是碰到記憶體洩漏或者記憶體錯誤,特別是對於大型的專案而言要去查乙個小小的記憶體洩漏可要花不少功夫的。目前已經有很多這方面的工具,比較著名的如rational purify,不過purify對linux的支援比較少,而且有一種洩漏是由於執行過程中不斷增長但是在程式結束的時候釋放的...
c c 中記憶體洩漏的檢查與避免
valgrind支援的工具 memcheck addrcheck cachegrind massid helgrind callgrind 執行時必須指明想用的工具,如果省略工具名,預設執行memcheck 檢測原理 1,當要讀寫記憶體中的某個位元組時,首先檢查這個位元組對應的a bit。如果該a ...
記憶體洩漏檢查
1.乙個指標多次進行賦值時,每次賦值後使用完後要釋放記憶體 coffsetcoedgemap poffsetcoedgemap polygonoffset ppoly,retpolygon,doffsetdis,enextend,0.1 expect true g ovldmgr.isvalid r...