繁体   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