Память не освобождена, но все еще достижима, это утечка? - PullRequest
13 голосов
/ 25 октября 2011

Проверяя с помощью 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 ]

19 голосов
/ 25 октября 2011

Нет, это не утечка памяти.
Это означает, что ваша программа все еще имеет ссылку на память, которая будет освобождена позже.

FAQ по Valgrind различаетследующие сообщения:

В чем заключается детектор утечки памяти Memcheck, в чем разница между «точно потерянным», «косвенно потерянным», «возможно потерянным», «все еще достижимым» и «подавленным»?

Подробности в разделе Memcheck руководства пользователя.

Вкратце:

  • определенно потеряно означает, что ваша программаутечка памяти - исправьте эти утечки!

  • косвенно потеряны означает, что ваша программа утечка памяти в структуре на основе указателя.(Например, если корневой узел двоичного дерева «определенно потерян», все дочерние элементы будут «косвенно потеряны».) Если вы исправите утечки definitely lost, утечки indirectly lost должны исчезнуть.

  • возможно потерян означает, что ваша программа утечка памяти, если вы не делаете смешные вещи с указателями.Иногда это разумно.
    Используйте --show-possibly-lost=no, если вы не хотите видеть эти отчеты.

  • все еще достижимо означает, что ваша программа, вероятно, в порядке - это не такосвободить память, которая могла бы быть.Это довольно часто и часто разумно.
    Не используйте --show-reachable=yes, если вы не хотите видеть эти отчеты.

  • подавлено означает, что ошибка утечки была подавлена.В файлах подавления по умолчанию есть некоторые подавления.Вы можете игнорировать подавленные ошибки.

1 голос
/ 25 октября 2011

Это зависит.

Это может быть настоящая утечка, а может и нет.Но в любом случае вы должны это исправить.

Если вы выделяете буфер и сохраняете его до конца программы, технически это утечка, но это не имеет значения - вы выделяете только один буфери он в основном постоянный.

С другой стороны, возможно, вы выделяете буфер таким образом, как это делается один раз в вашем тестовом коде, но позже с реальным кодом он может быть выделен более одного раза - тогдау вас есть утечка.

Так что лучше всего их исправить.

...