简体   繁体   English

内存未释放但仍可访问,是否泄漏?

[英]Memory not freed but still reachable, is it leaking?

By checking with valgrind, I see that 5 blocks of memory were not freed after terminating my program, but they are still reachable. 通过使用valgrind检查,我发现终止程序后没有释放5个内存块,但是它们仍然可以访问。 Do I need to be bothered by it? 我需要被它打扰吗?

And how it happens? 以及它是如何发生的?

zhanwu@gelata:~/sandbox$ valgrind ./a.out
==2430== Memcheck, a memory error detector
==2430== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==2430== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==2430== Command: ./a.out
==2430== 
Hello world!
Thread1 returns 1
Thread2 returns 10
Thread3 returns 10
==2430== 
==2430== HEAP SUMMARY:
==2430==     in use at exit: 1,590 bytes in 5 blocks
==2430==   total heap usage: 14 allocs, 9 frees, 2,442 bytes allocated
==2430== 
==2430== LEAK SUMMARY:
==2430==    definitely lost: 0 bytes in 0 blocks
==2430==    indirectly lost: 0 bytes in 0 blocks
==2430==      possibly lost: 0 bytes in 0 blocks
==2430==    still reachable: 1,590 bytes in 5 blocks
==2430==         suppressed: 0 bytes in 0 blocks
==2430== Rerun with --leak-check=full to see details of leaked memory
==2430== 
==2430== For counts of detected and suppressed errors, rerun with: -v
==2430== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

Below is my code, what can I do to free those 5 blocks if I intend to? 以下是我的代码,如果打算释放那5个块,该怎么办?

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

void* myfunction(void *ptr)
{
    static int n_call = 0;
    int *retval = malloc(sizeof(int));

    pthread_mutex_lock( &mutex1 );
    n_call++;
    *retval = n_call;
    pthread_mutex_unlock( &mutex1 );

    if(n_call < 2)
    {
        char *msg;
        msg = (char *)ptr;
        printf("%s\n", msg);

        return retval;
    }
    else
    {
        *retval = 10;
        pthread_exit(retval);
    }
}

int main(int argc, char *argv[])
{
    pthread_t t1, t2, t3;

    char *msg = "Hello world!";
    pthread_create(&t1, NULL, myfunction, (void *)msg);
    pthread_create(&t2, NULL, myfunction, (void *)msg);
    pthread_create(&t3, NULL, myfunction, (void *)msg);

    int **s1 = malloc(sizeof(int*));
    int **s2 = malloc(sizeof(int*));
    int **s3 = malloc(sizeof(int*));

    pthread_join(t1, (void **)s1);
    pthread_join(t2, (void **)s2);
    pthread_join(t3, (void **)s3);

    printf("Thread1 returns %d\n", **s1);
    printf("Thread2 returns %d\n", **s2);
    printf("Thread3 returns %d\n", **s3);

    free(*s1);
    free(*s2);
    free(*s3);

    free(s1);
    free(s2);
    free(s3);

    return 0;
}

No it is not a memory leak. 不,这不是内存泄漏。
It means your program still has reference to memory that will freed later. 这意味着您的程序仍然引用了稍后将释放的内存。

Valgrind FAQ differentiates between different messages as follows: Valgrind FAQ区分以下不同消息:

With Memcheck's memory leak detector, what's the difference between "definitely lost", "indirectly lost", "possibly lost", "still reachable", and "suppressed"? 使用Memcheck的内存泄漏检测器,“绝对丢失”,“间接丢失”,“可能丢失”,“仍然可达”和“被抑制”之间有什么区别?

The details are in the Memcheck section of the user manual. 详细信息在用户手册的Memcheck部分中。

In short: 简而言之:

  • definitely lost means your program is leaking memory -- fix those leaks! 绝对丢失意味着您的程序正在泄漏内存-修复这些泄漏!

  • indirectly lost means your program is leaking memory in a pointer-based structure. 间接丢失意味着您的程序正在基于指针的结构中泄漏内存。 (Eg if the root node of a binary tree is "definitely lost", all the children will be "indirectly lost".) If you fix the definitely lost leaks, the indirectly lost leaks should go away. (例如,如果二叉树的根节点“绝对丢失”,则所有子节点都将“间接丢失”。)如果修复了definitely lost泄漏,则indirectly lost泄漏应该消失。

  • possibly lost means your program is leaking memory, unless you're doing funny things with pointers. 可能丢失意味着您的程序正在泄漏内存,除非您使用指针做一些有趣的事情。 This is sometimes reasonable. 有时这是合理的。
    Use --show-possibly-lost=no if you don't want to see these reports. 如果您不想看到这些报告,请使用--show-possibly-lost=no

  • still reachable means your program is probably ok -- it didn't free some memory it could have. 仍然可以访问意味着您的程序可能还可以-它没有释放它可能拥有的一些内存。 This is quite common and often reasonable. 这是很常见的且通常是合理的。
    Don't use --show-reachable=yes if you don't want to see these reports. 如果您不想查看这些报告,请不要使用--show-reachable=yes

  • suppressed means that a leak error has been suppressed. “抑制”表示泄漏错误已得到抑制。 There are some suppressions in the default suppression files. 默认抑制文件中包含一些抑制。 You can ignore suppressed errors. 您可以忽略抑制的错误。

It depends. 这取决于。

It may well be a real leak, and it might not. 这很可能是真正的泄漏,也可能不是。 But either way you should fix it. 但是无论哪种方式,您都应该修复它。

If you allocate a buffer and keep it around all the way to the end of the program, technically it's a leak, but it doesn't matter - you only allocate one buffer, and it's basically permanent. 如果分配一个缓冲区并将其一直保留到程序末尾,从技术上讲这是一个泄漏,但是没关系-您只分配一个缓冲区,它基本上是永久的。

On the other hand perhaps you are allocating a buffer in a way that it's done just once in your test code, but later with the real code it might get allocated more than once - then you have a leak. 另一方面,也许您正在以一种只在测试代码中完成一次的方式来分配缓冲区,但是后来在实际代码中,它可能会被分配多次以上,这会导致泄漏。

So it's best to fix them all. 因此,最好将它们全部修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM