内存没有被释放但仍然可以访问,它是否泄漏?

时间:2011-10-25 07:45:04

标签: c memory pthreads valgrind

通过检查valgrind,我看到在终止程序后没有释放5块内存,但它们仍然可以访问。我需要被它打扰吗?

它是如何发生的?

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)

下面是我的代码,如果我想打算那么我可以做些什么来释放这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;
}

2 个答案:

答案 0 :(得分:19)

不,这不是内存泄漏 这意味着您的程序仍然引用将在以后释放的内存。

Valgrind FAQ 区分不同的消息,如下所示:

  

使用Memcheck的内存泄漏检测器,“绝对丢失”,“间接丢失”,“可能丢失”,“仍然可以访问”和“抑制”之间的区别是什么?

     

详情请参阅用户手册的Memcheck部分。

     

简而言之:

     
      
  • 肯定丢失意味着您的程序泄露内存 - 修复这些泄漏!

  •   
  • 间接丢失表示您的程序在基于指针的结构中泄漏内存。 (例如,如果二叉树的根节点“肯定丢失”,则所有子节点将“间接丢失”。)如果修复definitely lost泄漏,indirectly lost泄漏应该消失。 / p>

  •   
  • 可能丢失意味着你的程序正在泄漏内存,除非你用指针做有趣的事情。这有时是合理的   如果您不想看到这些报告,请使用--show-possibly-lost=no

  •   
  • 仍然可以访问意味着您的程序可能没问题 - 它没有释放它可能拥有的内存。这很常见,而且往往是合理的   如果您不想看到这些报告,请不要使用--show-reachable=yes

  •   
  • 已压制表示已阻止泄漏错误。默认抑制文件中存在一些抑制。您可以忽略已删除的错误。

  •   

答案 1 :(得分:1)

取决于。

这可能是真正的泄漏,也可能不是。但无论哪种方式你都应该解决它。

如果你分配一个缓冲区并一直保持到程序结束,从技术上讲它是一个泄漏,但没关系 - 你只分配一个缓冲区,它基本上是永久性的。

另一方面,也许你正在以一种在测试代码中只完成一次的方式分配一个缓冲区,但是后来使用实际代码它可能会多次分配 - 然后你就会泄漏。

所以最好全部修复它们。