今天又溫習了一下linux下檢測內存洩漏工具vargrind的使用:
1. 從網上看,大家都用的是valgrind工具集,valgrind包含了幾種工具:
(1) memcheck:檢查程序中的內存問題,如洩漏、越界、非法指針等。
(2) callgrind:檢測程序代碼的運行時間和調用過程,以及分析程序性能。
(3) cachegrind:分析CPU的cache命中率、丟失率,用於進行代碼優化。
(4) helgrind:用於檢查多線程程序的競態條件。
(5) massif:堆棧分析器,指示程序中使用了多少堆內存等信息。
2. 只說memcheck這個工具,它負責檢測內存問題:
(1) 使用未初始化的內存,這塊內存的值是隨機的。
(2) 使用未指向有效內存的指針,即空指針或者野指針。
(3) 內存越界方法。
(4) 內存復制區域的重疊。
使用未初始化的內存 (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)
重復free
3. 使用方法:
valgrind 選項--tool=name,name指定使用哪個工具,比如memcheck等。
Memcheck選項:
-leak-check=no|summary|full 要求對leak給出詳細信息,即內存洩漏的詳細信息。
4. 例子說明1:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *p; *p = 'a'; return 0; }使用分配內存且未初始化的指針p,檢測如下:
[ljq@ycy valgrind]$ valgrind --tool=memcheck ./mem-leak
==1841== Memcheck, a memory error detector
==1841== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==1841== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==1841== Command: ./mem-leak
==1841==
==1841== Use of uninitialised value of size 4
==1841== at 0x8048404: main (mem-leak.c:8)
==1841==
==1841==
==1841== HEAP SUMMARY:
==1841== in use at exit: 0 bytes in 0 blocks
==1841== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==1841==
==1841== All heap blocks were freed -- no leaks are possible
==1841==
==1841== For counts of detected and suppressed errors, rerun with: -v
==1841== Use --track-origins=yes to see where uninitialised values come from
==1841== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
以上是valgrind命令檢測結果的輸出,
==1841== Use of uninitialised value of size 4 指出使用未初始化的值
==1841== at 0x8048404: main (mem-leak.c:8) 指出代碼位置行數
例子說明2:分配內存,不進行釋放。
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *p = malloc(sizeof(char) * 100); return 0; }[ljq@ycy valgrind]$ valgrind --tool=memcheck --leak-check=full ./mem-leak2
==1901== Memcheck, a memory error detector
==1901== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==1901== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==1901== Command: ./mem-leak2
==1901==
==1901==
==1901== HEAP SUMMARY: 堆的統計信息:
==1901== in use at exit: 100 bytes in 1 blocks
==1901== total heap usage: 1 allocs, 0 frees, 100 bytes allocated 堆heap上分配了一次內存,100字節
==1901==
==1901== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1 指出100字節丟失即沒有釋放
==1901== at 0x402A2C2: malloc (vg_replace_malloc.c:299)
==1901== by 0x8048445: main (mem-leak2.c:7) mem-leak2.c的第7行發生內存洩漏
==1901==
==1901== LEAK SUMMARY: leak-check選項的統計信息:
==1901== definitely lost: 100 bytes in 1 blocks 100字節絕對丟失
==1901== indirectly lost: 0 bytes in 0 blocks
==1901== possibly lost: 0 bytes in 0 blocks
==1901== still reachable: 0 bytes in 0 blocks
==1901== suppressed: 0 bytes in 0 blocks
==1901==
==1901== For counts of detected and suppressed errors, rerun with: -v
==1901== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
以後工作中慢慢用吧。