[英]Understand memory leak types in valgrind memcheck tool
我正在使用Valgrind工具來了解不同類型的內存泄漏:直接丟失,間接丟失仍然可以訪問甚至可能丟失。 示例1:
#include<stdio.h>
#include <stdlib.h>
main() {
int *p, i;
p = malloc(10*sizeof(int));
for(i = 0;i < 10;i++)
p[i] = i;
//free(p);
printf("Freed\n ");
}
LEAK SUMMARY:
==31770== definitely lost: 0 bytes in 0 blocks
==31770== indirectly lost: 0 bytes in 0 blocks
==31770== possibly lost: 20 bytes in 1 blocks
==31770== still reachable: 0 bytes in 0 blocks
==31770== suppressed: 0 bytes in 0 blocks
eg2:
main() {
int *p, i;
p = malloc(10*sizeof(int));
// printf("freed");
}
LEAK SUMMARY:
==14950== definitely lost: 0 bytes in 0 blocks
==14950== indirectly lost: 0 bytes in 0 blocks
==14950== possibly lost: 0 bytes in 0 blocks
==14950== still reachable: 40 bytes in 1 blocks
==14950== suppressed: 0 bytes in 0 blocks
If a uncomment the printf statement:
LEAK SUMMARY:
==15889== definitely lost: 40 bytes in 1 blocks
==15889== indirectly lost: 0 bytes in 0 blocks
==15889== possibly lost: 0 bytes in 0 blocks
==15889== still reachable: 0 bytes in 0 blocks
==15889== suppressed: 0 bytes in 0 blocks
請為我詳細解釋這些不同的內存泄漏。
快速的互聯網搜索可以訪問以下站點:
http://valgrind.org/docs/manual/faq.html#faq.deflost
詳細信息在用戶手冊的Memcheck部分中。
簡而言之:
“絕對丟失”表示您的程序正在泄漏內存-修復這些泄漏!
“間接丟失”表示您的程序正在基於指針的結構中泄漏內存。 (例如,如果二叉樹的根節點“絕對丟失”,則所有子代都將“間接丟失”。)如果修復“絕對丟失”的泄漏,則“間接丟失”的泄漏應該消失。
“可能丟失”表示您的程序正在泄漏內存,除非您使用指針做異常的事情,這些指針可能導致它們指向已分配的塊的中間。 有關某些可能的原因,請參見用戶手冊。 如果您不想看到這些報告,請使用--show-possfully-lost = no。
“仍然可以訪問”意味着您的程序可能還可以-它沒有釋放它可能擁有的一些內存。 這是很常見的且通常是合理的。 如果您不想查看這些報告,請不要使用--show-reachable = yes。
“被抑制”表示泄漏錯誤已得到抑制。 默認抑制文件中包含一些抑制。 您可以忽略抑制的錯誤。
更新:
“絕對丟失”和“仍然可以到達”之間的區別如下:如果所有對它的引用都消失了並且您之前沒有釋放過它,則內存肯定會丟失 -這是內存泄漏的經典情況。 時,在你的程序的生命周期結束,你沒有釋放這是動態分配的,但還是有它有效的引用的所有內存,以便它可以釋放它仍然是可到達 。
由於無論如何在程序終止時都會釋放程序的所有內存,因此通常這不是問題。 但是對於長時間運行的程序和較大的內存分配,如果您不再需要它們,則值得手動釋放它們。
讓我給你看一個簡單的例子:
#include <stdio.h>
#include <stdlib.h>
char *still_reachable;
char *definitely_lost_global;
int main()
{
char *definitely_lost_local;
// allocate 10 bytes of memory -> will get lost
definitely_lost_local = malloc(10 * sizeof *definitely_lost_local);
// allocate 20 bytes of memory -> will get lost
definitely_lost_global = malloc(20 * sizeof *definitely_lost_global);
definitely_lost_global = NULL;
// Now there aren't any references to those 20 bytes anymore, so memory is lost.
// allocate 40 bytes of memory. The global pointer has static storage duration.
// We do not change the pointer, so the respective memory will
// be still reachable by the end of program lifetime
still_reachable = malloc(40 * sizeof *still_reachable);
} // scope of definitely_lost_local ends here --> 10 bytes are lost!
我們可以猜測在此示例中將丟失10 + 20 = 30個字節,而仍然可以訪問40個字節。 因此,讓我們用valgrind檢查一下:
==19474== Memcheck, a memory error detector
==19474== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==19474== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==19474== Command: ./prog
==19474==
==19474==
==19474== HEAP SUMMARY:
==19474== in use at exit: 70 bytes in 3 blocks
==19474== total heap usage: 3 allocs, 0 frees, 70 bytes allocated
==19474==
==19474== LEAK SUMMARY:
==19474== definitely lost: 30 bytes in 2 blocks
==19474== indirectly lost: 0 bytes in 0 blocks
==19474== possibly lost: 0 bytes in 0 blocks
==19474== still reachable: 40 bytes in 1 blocks
==19474== suppressed: 0 bytes in 0 blocks
==19474== Rerun with --leak-check=full to see details of leaked memory
==19474==
==19474== For counts of detected and suppressed errors, rerun with: -v
==19474== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
如預期的那樣,Voilá。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.