Еще можно добраться обнаружена утечка в отчет


все функции, упомянутые в этом блоке библиотечные функции. Как я могу исправить эту утечку памяти?

он указан под "все еще доступен категория". (Есть еще 4, которые очень похожи, но разных размеров)

 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)

Лови: как только я запустил свою программу, она не дала утечек памяти, но у нее была одна дополнительная строка в выводе Valgrind, которой раньше не было:

отбрасывание syms at 0x5296fa0-0x52af438 in /lib / libgcc_s-4.4.4-20100630. so. 1 благодаря munmap ()

Если утечка не может быть исправлена, может ли кто-нибудь объяснить, почему линия munmap() заставляет Valgrind сообщать о 0 "все еще доступных" утечках?

Edit:

вот минимальный тестовый пример:

#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 %dn",i);
            exit(1);
        }
    }


    for(i=0;i<(n+n-1);i++) {
        pthread_join(threadIdArray[i],NULL);
    }

    free(threadIdArray);

    return(0);
}

запустить с:

valgrind -v --leak-check=full --show-reachable=yes ./a.out
4 115

4 ответа:

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

первое широко используемое определение "утечки памяти": "Память была выделена и впоследствии не была освобождена до завершения программы."Однако многие программисты (справедливо) утверждают, что определенные типы утечек памяти, соответствующие этому определению, на самом деле не представляют никакой проблемы и поэтому не должны следует считать правда "утечки памяти".

возможно, более строгое (и более полезное) определение "утечки памяти": "Память была выделена и не может впоследствии освободили, потому что программа больше не имеет никаких указателей на выделенный блок памяти.- Другими словами, вы не можете освободить память, на которую у вас больше нет указателей. Таким образом, такая память является "утечкой памяти". Valgrind использует это более строгое определение термина "утечка памяти". Это тот тип утечка, которая потенциально может привести к значительному истощению кучи, особенно для долгоживущих процессов.

категория "все еще достижимая "в отчете об утечке Valgrind относится к распределениям, которые соответствуют только первому определению"утечки памяти". Эти блоки не были освобождены, но они могли быть освобождены (если бы программист захотел), потому что программа все еще отслеживала указатели на эти блоки памяти.

В общем, нет необходимости беспокоиться о "еще достижимые " блоки. Они не представляют такой проблемы, что правда утечка памяти может вызвать. Например, обычно нет потенциала для исчерпания кучи из" все еще доступных " блоков. Это связано с тем, что эти блоки обычно являются единовременными распределениями, ссылки на которые сохраняются в течение всего времени существования процесса. В то время как вы могли бы пройти и убедиться, что ваша программа освобождает все выделенная память, обычно нет никакой практической пользы от этого поскольку операционная система в любом случае восстановит всю память процесса после завершения процесса. Сравните это с правда утечки памяти, которые, если их оставить незафиксированными, могут привести к тому, что процесс исчерпает память, если он будет работать достаточно долго, или просто заставит процесс потреблять гораздо больше памяти, чем необходимо.

вероятно, единственный раз, когда полезно убедиться, что все распределения имеют соответствующие "освобождения", если ваши инструменты обнаружения утечек не могут определить, какие блоки "все еще достижимо" (но Valgrind может это сделать) или если ваша операционная система не восстанавливает всю память завершающего процесса (все платформы, которые Valgrind был перенесен для этого).

поскольку есть некоторая процедура из семейства pthread внизу (но я не знаю, что именно), я предполагаю, что вы запустили какой-то поток как соединяемый, который завершил выполнение.

информация о состоянии выхода из этого потока остается доступной до тех пор, пока вы не вызовете pthread_join. Таким образом, память хранится в записи потерь при завершении программы, но она все еще доступна, так как вы можете использовать pthread_join для доступа к нему.

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

Edit: Я проверил ваш пример программы (после некоторых очевидных исправлений) и у меня нет ошибок, но после

==18933== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
--18933-- 
--18933-- used_suppression:      2 dl-hack3-cond-1
--18933-- used_suppression:      2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a

С dl- вещь напоминает многое из того, что вы видите я думаю, что вы видите известную проблему, которая имеет решение с точки зрения файла подавления для valgrind. Возможно, ваша система не обновлена, или ваш дистрибутив не поддерживает их вещи. (Мой ubuntu 10.4, 64bit)

Вы, кажется, не понимаете, что still reachable средства.

что-нибудь still reachable и не утечка. Тебе не нужно ничего с этим делать.

вот правильное объяснение "все еще достижимо":

" все еще достижимы " - это утечки, назначенные глобальным и статическим локальным переменным. Поскольку valgrind отслеживает глобальные и статические переменные, он может исключить выделение памяти, назначенное "один раз и забыть". Глобальная переменная назначила распределение один раз и никогда не переназначала это распределение, как правило, не является "утечкой" в том смысле, что оно не растет бесконечно. Это все еще утечка в строгом смысле, но обычно может быть игнорируется, если вы не педант.

локальные переменные, которым назначены распределения и которые не являются свободными, почти всегда являются утечками.

вот пример

int foo(void)
{
    static char *working_buf = NULL;
    char *temp_buf;
    if (!working_buf) {
         working_buf = (char *) malloc(16 * 1024);
    }
    temp_buf = (char *) malloc(5 * 1024);

    ....
    ....
    ....

}

Valgrind сообщит working_buf как " все еще достижимый-16k "и temp_buf как"определенно потерянный - 5k".