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