簡體   English   中英

了解Valgrind Memcheck工具中的內存泄漏類型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM