系統編程中一個重要的方面就是有效地處理與內存相關的問題。你的工作越接近系統,你就需要面對越多的內存問題。有時這些問題非常瑣碎,而更多時候它會演變成一個調試內存問題的惡夢。所以,在實踐中會用到很多工具來調試內存問題。
Valgrind是運行在Linux上一套基於仿真技術的程序調試和分析工具,它包含一個內核——一個軟件合成的CPU,和一系列的小工具,每個工具都可以完成一項任務──調試,分析,或測試等。Valgrind可以檢測內存洩漏和內存違例,還可以分析cache的使用等,靈活輕巧而又強大,能直穿程序錯誤的心髒,真可謂是程序員的瑞士軍刀。
Valgrind工具包包含多個工具:
Memcheck是一個內存錯誤檢測器。它有助於使你的程序,尤其是那些用C和C++寫的程序,更加准確。Cachegrind是一個緩存和分支預測分析器。它有助於使你的程序運行更快。Callgrind是一個調用圖緩存生成分析器。它與Cachegrind的功能有重疊,但也收集Cachegrind不收集的一些信息Helgrind是一個線程錯誤檢測器。它有助於使你的多線程程序更加准確。DRD也是一個線程錯誤檢測器。它和Helgrind相似,但使用不同的分析技術,所以可能找到不同的問題。Massif是一個堆分析器。它有助於使你的程序使用更少的內存。DHAT是另一種不同的堆分析器。它有助於理解塊的生命期、塊的使用和布局的低效等問題。SGcheck是一個實驗工具,用來檢測堆和全局數組的溢出。它的功能和Memcheck互補:SGcheck找到Memcheck無法找到的問題,反之亦然。BBV是個實驗性質的SimPoint基本塊矢量生成器。它對於進行計算機架構的研究和開發很有用處。
這裡給大家介紹如何使用Valgrind memcheck工具進行C/C++的內存洩漏檢測。memcheck工具主要檢查下面的程序錯誤:
使用未初始化的內存 (Use of uninitialised memory)使用已經釋放了的內存 (Reading/writingmemory after it has been free’d)使用超過 malloc分配的內存空間(Reading/writing off the end of malloc’d blocks)對堆棧的非法訪問 (Reading/writinginappropriate 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)
#include#include int main(void) { char *p; char c = *p; //使用未初始化的內存 printf( [%c] ,c); return 0; }
#include#include int main(void) { char *p = malloc(1); *p = 'a'; char c = *p; printf( [%c] ,c); free(p); c = *p;//在內存被釋放後進行讀/寫 return 0; }
#include#include int main(void) { char *p = malloc(1); *p = 'a'; char c = *(p+1); //從已分配內存塊的尾部進行讀/寫 printf( [%c] ,c); free(p); return 0; }
#include#include //在這次的代碼中, 我們申請了一個字節但是沒有將它釋放 int main(void) { char *p = malloc(1); *p = 'a'; char c = *p; printf( [%c] ,c); return 0; }
#include#include #include int main(void) { char *p = (char*)malloc(1); *p = 'a'; char c = *p; printf( [%c] ,c); delete p; return 0; }
調試結果如下:
#include#include int main(void) { char *p = (char*)malloc(1); *p = 'a'; char c = *p; printf( [%c] ,c); free(p); free(p); return 0; }