Todas as funções mencionadas neste bloco são funções de biblioteca. Como posso corrigir esse vazamento de memória?
Ele está listado na categoria " Ainda acessível ". (Existem mais 4, que são muito semelhantes, mas de tamanhos variados)
630 bytes in 1 blocks are still reachable in loss record 5 of 5
at 0x4004F1B: calloc (vg_replace_malloc.c:418)
by 0x931CD2: _dl_new_object (dl-object.c:52)
by 0x92DD36: _dl_map_object_from_fd (dl-load.c:972)
by 0x92EFB6: _dl_map_object (dl-load.c:2251)
by 0x939F1B: dl_open_worker (dl-open.c:255)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0x9399C5: _dl_open (dl-open.c:584)
by 0xA64E31: do_dlopen (dl-libc.c:86)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0xA64FF4: __libc_dlopen_mode (dl-libc.c:47)
by 0xAE6086: pthread_cancel_init (unwind-forcedunwind.c:53)
by 0xAE61FC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
Captura: Uma vez que executei meu programa, não houve vazamentos de memória, mas havia uma linha adicional na saída Valgrind, que não estava presente antes:
Descartar syms em 0x5296fa0-0x52af438 em /lib/libgcc_s-4.4.4-20100630.so.1 devido ao munmap ()
Se o vazamento não puder ser corrigido, alguém pode pelo menos explicar por que a linha munmap () faz com que Valgrind relate 0 vazamentos "ainda acessíveis"?
Editar:
Aqui está uma amostra mínima de teste:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *runner(void *param) {
/* some operations ... */
pthread_exit(NULL);
}
int n;
int main(void) {
int i;
pthread_t *threadIdArray;
n=10; /* for example */
threadIdArray = malloc((n+n-1)*sizeof(pthread_t));
for(i=0;i<(n+n-1);i++) {
if( pthread_create(&threadIdArray[i],NULL,runner,NULL) != 0 ) {
printf("Couldn't create thread %d\n",i);
exit(1);
}
}
for(i=0;i<(n+n-1);i++) {
pthread_join(threadIdArray[i],NULL);
}
free(threadIdArray);
return(0);
}
Correr com:
valgrind -v --leak-check=full --show-reachable=yes ./a.out
Respostas:
Há mais de uma maneira de definir "vazamento de memória". Em particular, existem duas definições principais de "vazamento de memória" que são comuns entre os programadores.
A primeira definição comumente usada de "vazamento de memória" é "Memória foi alocada e não foi liberada posteriormente antes do término do programa". No entanto, muitos programadores (com razão) argumentam que certos tipos de vazamentos de memória que se encaixam nessa definição não representam nenhum tipo de problema e, portanto, não devem ser considerados verdadeiros "vazamentos de memória".
Uma definição discutivelmente mais rígida (e mais útil) de "vazamento de memória" é: "A memória foi alocada e não pode ser liberada posteriormente porque o programa não possui mais ponteiros para o bloco de memória alocado". Em outras palavras, você não pode liberar memória para a qual não possui mais ponteiros. Essa memória é, portanto, um "vazamento de memória". Valgrind usa essa definição mais rigorosa do termo "vazamento de memória". Esse é o tipo de vazamento que pode causar um esgotamento significativo do heap, especialmente para processos de longa duração.
A categoria "ainda acessível" no relatório de vazamento da Valgrind refere-se a alocações que se encaixam apenas na primeira definição de "vazamento de memória". Esses blocos não foram liberados, mas poderiam ter sido liberados (se o programador quisesse) porque o programa ainda estava acompanhando os ponteiros para esses blocos de memória.
Em geral, não há necessidade de se preocupar com blocos "ainda acessíveis". Eles não representam o tipo de problema que os verdadeiros vazamentos de memória podem causar. Por exemplo, normalmente não há potencial para esgotamento de heap de blocos "ainda acessíveis". Isso ocorre porque esses blocos geralmente são alocações únicas, cujas referências são mantidas durante toda a vida útil do processo. Embora você possa verificar e garantir que seu programa libere toda a memória alocada, geralmente não há nenhum benefício prático, pois o sistema operacional recuperará toda a memória do processo após o término do processo. Compare isso com true vazamentos de memória que, se deixados sem correção, podem causar falta de memória em um processo, se deixados em execução por tempo suficiente ou simplesmente causar um processo que consome muito mais memória do que o necessário.
Provavelmente, o único momento em que é útil garantir que todas as alocações tenham "liberações" correspondentes é que suas ferramentas de detecção de vazamentos não conseguem dizer quais blocos "ainda são alcançáveis" (mas a Valgrind pode fazer isso) ou se o sistema operacional não recupera todas as a memória de um processo de término (todas as plataformas para as quais o Valgrind foi portado para isso).
fonte
munmap
seja invocado como resultado do descarregamento de um objeto compartilhado. E todos os recursos usados pelo objeto compartilhado podem estar sendo liberados antes de serem descarregados. Isso poderia explicar por que os "ainda acessíveis" estão sendo liberados nomunmap
caso. Só estou especulando aqui. Não há informações suficientes aqui para ter certeza.Como existe uma rotina da família pthread na parte inferior (mas eu não conheço essa em particular), meu palpite seria que você lançou algum encadeamento como junção que encerrou a execução.
As informações do estado de saída desse encadeamento são mantidas disponíveis até você ligar
pthread_join
. Portanto, a memória é mantida em um registro de perda na finalização do programa, mas ainda é acessível, pois você pode usápthread_join
-la para acessá-la.Se essa análise estiver correta, inicie esses encadeamentos desanexados ou junte-se a eles antes de encerrar seu programa.
Editar : executei seu programa de amostra (após algumas correções óbvias) e não tenho erros, mas o seguinte
Como a
dl-
coisa se parece muito com o que você vê, acho que você vê um problema conhecido que tem uma solução em termos de arquivo de supressãovalgrind
. Talvez seu sistema não esteja atualizado ou sua distribuição não mantenha essas coisas. (O meu é o ubuntu 10.4, 64bit)fonte
Você não parece entender o que
still reachable
significa.Qualquer coisa não
still reachable
é um vazamento. Você não precisa fazer nada sobre isso.fonte
FILE
indicadores perdidos ?Aqui está uma explicação adequada de "ainda acessível":
"Ainda acessível" são vazamentos atribuídos a variáveis globais e estáticas-locais. Como o valgrind rastreia variáveis globais e estáticas, ele pode excluir alocações de memória designadas como "uma vez e esquecer". Uma variável global atribuiu uma alocação uma vez e nunca reatribuiu essa alocação normalmente não é um "vazamento" no sentido de que não cresce indefinidamente. Ainda é um vazamento no sentido estrito, mas geralmente pode ser ignorado, a menos que você seja pedante.
Variáveis locais às quais são atribuídas alocações e não liberadas quase sempre são vazamentos.
Aqui está um exemplo
Valgrind relatará working_buf como "ainda acessível - 16k" e temp_buf como "definitivamente perdido - 5k".
fonte
Para futuros leitores, "Ainda acessível" pode significar que você esqueceu de fechar algo como um arquivo. Embora isso não pareça assim na pergunta original, você deve sempre garantir que fez isso.
fonte