Память не освобождена, но все еще доступна, это утечка?
Проверяя valgrind, я вижу, что после завершения моей программы 5 блоков памяти не были освобождены, но они все еще доступны. Нужно ли это беспокоить?
И как это происходит?
[email protected]:~/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;
}
Ответы
Ответ 1
Нет, это не утечка памяти.
Это означает, что ваша программа все еще имеет ссылку на память, которая будет освобождена позже.
Valgrind FAQ различает различные сообщения следующим образом:
С детектором течи памяти Memcheck, какая разница между "определенно потерянной", "косвенно потерянной", "возможно потерянной", "все еще достижимой" и "подавленной"?
Подробности приведены в разделе Memcheck руководства пользователя.
Короче:
-
определенно потерянный означает, что ваша программа утечки памяти - исправить эти утечки!
-
косвенно потерянный означает, что ваша программа протекает в памяти в структуре, основанной на указателях. (Например, если корень node двоичного дерева "определенно потерян", все дети будут "косвенно потеряны".) Если вы исправите утечки definitely lost
, утечки indirectly lost
должны исчезнуть.
-
возможно потерянный означает, что ваша программа утечки памяти, если вы не делаете забавные вещи с указателями. Это иногда разумно. Используйте --show-possibly-lost=no
, если вы не хотите видеть эти отчеты.
-
все еще доступный означает, что ваша программа, вероятно, хорошо - она не освобождает память, которую она могла бы иметь. Это довольно часто и часто разумно. Не используйте --show-reachable=yes
, если вы не хотите видеть эти отчеты.
-
подавлено означает, что ошибка утечки была подавлена. В файлах подавления по умолчанию есть некоторые пресечения. Вы можете игнорировать подавленные ошибки.
Ответ 2
Это зависит.
Это может быть настоящая утечка, и это может быть не так. Но в любом случае вы должны это исправить.
Если вы выделяете буфер и поддерживаете его до конца программы, технически это утечка, но это не имеет значения - вы выделяете только один буфер и в основном постоянны.
С другой стороны, возможно, вы выделяете буфер таким образом, который он выполнял только один раз в вашем тестовом коде, но позже с реальным кодом он может быть выделен более одного раза - тогда у вас есть утечка.
Поэтому лучше всего их исправить.