天天看點

C/C++查找記憶體洩露的方法C/C++查找記憶體洩露的方法

C/C++查找記憶體洩露的方法

文章目錄

  • C/C++查找記憶體洩露的方法
    • 工具概括
    • 一、利用valgrind的memcheck工具動态檢測記憶體洩露
      • 檢測内容:
      • 檢測方法:
      • 檢測結果:
    • 二、利用cppcheck工具靜态檢測記憶體洩露
      • 檢測内容:
      • 檢測方法:
      • 檢測結果:
    • 三、利用valgrind的massif工具動态檢測記憶體洩露
      • 檢測内容:
      • 檢測方法:
      • 檢測結果:
項目實際經驗總結!!!靠以下幾種工具查找記憶體洩露,快速且準确!大家可以看前面的概括,選擇适合自己情況的工具,來查找記憶體洩露。希望大家的代碼都能無bug、完美運作!

工具概括

1、memcheck:适合檢測程式運作短時間内出現的記憶體洩露;

2、cppcheck:适合檢測一些我們可能忽略的代碼錯誤。在代碼中,有一些情況在程式運作中很少會發生,進而容易疏忽這些情況下的記憶體管理,而導緻記憶體洩露,可以由此工具檢測出來;

3、massif:适合檢測程式運作長時間内出現的記憶體洩露。随着運作時間變長,有些配置設定的記憶體一直不被釋放,或者還在逐漸申請新的記憶體,導緻程式占用的記憶體随着運作時間逐漸增長,這時我們就需要好好注意這部分代碼;

一、利用valgrind的memcheck工具動态檢測記憶體洩露

檢測内容:

· 使用未初始化的記憶體(Use of uninitialised memory)

· 使用已經釋放了的記憶體(Reading/writing memory after it has been free’d)

· 使用超過malloc配置設定的記憶體空間(Reading/writing off the end of malloc’d blocks)

· 對堆棧的非法通路(Reading/writing inappropriate areas on the stack)

· 申請的空間是否有釋放(Memory leaks – where pointers to malloc’d blocks are lost forever)

· malloc/free/new/delete申請和釋放記憶體的比對(Mismatched use of malloc/new/new [] vs free/delete/delete [])

· src和dst的重疊(Overlapping src and dst pointers in memcpy() and related functions)

檢測方法:

  • a、安裝valgrind
//1.進入網站下載下傳源碼
http://valgrind.org/downloads/current.html#current

//2.解壓,然後進入解壓後的目錄
tar -jxf valgrind-3.13.0.tar.bz2

//3.安裝
./configure --prefix=/home/valgrind(安裝路徑)
make
make install

//4.檢視版本
valgrind --version
           
  • b、使用:
valgrind --tool=memcheck --leak-check=full --trace-children=yes --show-reachable=yes --log-file=error.log ./pss_client
           

1、–tool=memcheck:選擇memcheck工具來對程式進行記憶體檢查;

2、–leak-check=full:完全檢查記憶體洩露;

3、–trace-children=yes:是否對子程序進行跟蹤;

4、 --show-reachable=yes:定位記憶體洩漏位置(具體到哪個函數的哪一行)

5、–log-file=error.log:将檢測到的記憶體問題儲存到error.log檔案當中;

6、./pss_client:運作我們的程式;

檢測結果:

  • 使用該工具并沒有檢測出我們的程式在整個運作過程存在記憶體洩露:
==14368== 
==14368== HEAP SUMMARY:
==14368==     in use at exit: 0 bytes in 0 blocks
==14368==   total heap usage: 1,137 allocs, 1,137 frees, 5,603,265 bytes allocated
==14368== 
==14368== All heap blocks were freed -- no leaks are possible
==14368== 
==14368== For counts of detected and suppressed errors, rerun with: -v
==14368== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
           

二、利用cppcheck工具靜态檢測記憶體洩露

檢測内容:

  • error:出現的錯誤
  • warning:為了預防bug防禦性程式設計建議資訊;
  • style:編碼格式問題(沒有使用的函數、多餘的代碼等);
  • portablity:移植性警告。該部分如果移植到其他平台上,可能出現相容性問題;
  • performance:建議優化該部分代碼的性能;
  • information:一些有趣的資訊,可以忽略不看的;

檢測方法:

  • a、安裝cppcheck
//1.進入網站下載下傳源碼
https://sourceforge.net/projects/cppcheck/

//2.解壓,然後進入解壓後的目錄
tar -zxvf cppcheck-1.8.0.tar.gz

//3.安裝
make
sudo make install

//4.檢視版本
cppcheck --version
           
  • b、使用:
cppcheck --xml-version=2 --enable=all  /src 2> error.log
           

1、–xml-version=2:将檢測結果以xml格式輸出;

2、–enable=all:檢測all是檢查上述檢測内容中的所有;預設情況下檢測error,也可以檢測warning/style等,

3、/src:檢測src目錄下的所有檔案,也可以檢測單個檔案,如:main.c

4、2> error.log:将檢測結果儲存到error.log檔案當中;

檢測結果:

  • 該工具檢測出,在一些出錯情況下,直接return了,沒有對此前malloc/calloc的記憶體進行釋放;
<error id="memleak" severity="error" msg="Memory leak: state" verbose="Memory leak: state" cwe="401">
            <location file="pss_event_epoll.c" line="33"/>
</error>
           
  • 如下列代碼,state可能沒被釋放,而導緻記憶體洩露:
pss_event_api_state_t *state = (pss_event_api_state_t *)calloc(1, sizeof(pss_event_api_state_t));
    if (!state) {
        PSS_LOGE("epoll api state error,:%s \n", strerror(errno));
        return -1;
    }

    state->events = (struct epoll_event *)calloc(1, sizeof(struct epoll_event) * event_loop->set_size);
    if (!state->events) {
        PSS_LOGE("epoll api state event error,:%s \n", strerror(errno));
        return -1; //如在此處return ,前面calloc的state沒有free
    }
           

三、利用valgrind的massif工具動态檢測記憶體洩露

檢測内容:

  • massif是一個堆分析器,它統計程式使用的堆記憶體大小(由malloc等函數配置設定的記憶體;
  • 堆分析可以幫助減少程式使用的記憶體。如果配置設定的記憶體還沒有釋放并且指針也在,這種情況對于Memcheck(記憶體洩漏檢查器)來說不算錯誤。但是随着時間記憶體增加,這也算記憶體洩漏,Massif可以幫助識别這些洩漏;
  • 重要的是,Massif不僅會報告程式正在使用多少堆記憶體,還會提供非常詳細的資訊,來指明這些記憶體是由程式中哪部分配置設定的;

檢測方法:

  • a、安裝valgrind
//1.進入網站下載下傳源碼
http://valgrind.org/downloads/current.html#current

//2.解壓,然後進入解壓後的目錄
tar -jxf valgrind-3.13.0.tar.bz2

//3.安裝
./configure --prefix=/home/valgrind(安裝路徑)
make
make install

//4.檢視版本
valgrind --version
           
  • b、使用:
valgrind --tool=massif --time-unit=B --detailed-freq=1 ./pss   client
           

1、–tool=massif:選擇memcheck工具來記錄程式運作過程中的堆記憶體變化;

2、–time-unit=B:快照采集時間,B的意思是以位元組為機關來記錄堆記憶體的變化;

3、–detailed-freq=1:設定詳細快照的頻率,當設定為1時,每個快照都被記錄成詳細的;

檢測結果:

  • 當程式運作停止後,會生成一個massif.out.29296檔案(29296是程式的PID);
  • 使用massif-visualizer工具來檢視此檔案:
1.安裝massif-visualizer
sudo apt-get install massif-visualizer

2.啟動
massif-visualizer

3.啟動之後,選擇程式運作生成的massif.out.29296檔案打開,就能看到程式運作時的堆記憶體使用情況了;
           
  • 大家可以參考該文章,教你如何看懂massif顯示出來的記憶體使用情況 堆問題分析的利器——valgraind的massif

繼續閱讀