2016-10-14 2 views
1

я это (плохо) кодКак освободить память для указателя в C

void function(deq** dq, int data) 
{ 
    // TODO: add a new element at the end of the queue 
    deq *temp = (dequeue*)malloc(sizeof(dequeue)); 
    deq *copy = (*dq); 
    temp->data = data; 


    if (copy == NULL) { 
    temp->next = NULL; 
    temp->prev = NULL; 
    (*dq) = temp; 
    } 
    else{ 
    while (copy->next != NULL) { 
     copy = copy->next; 
    } 

    temp->prev = copy; 
    temp->next = NULL; 
    copy->next = temp; 
    (*dq) = temp; 
    } 

    //free(temp); 
} 

, что моя проблема в том, что я не могу бесплатно темп без сбоев программки есть способ решить эту проблему? и может кто-то сказать мне, почему, когда я использую это бесплатно, я не могу запустить программу, но с valgrind это работает ... так смешно.

==17186== HEAP SUMMARY: 
==17186==  in use at exit: 216 bytes in 9 blocks 
==17186== total heap usage: 15 allocs, 6 frees, 360 bytes allocated 
==17186== 
==17186== 72 (24 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 8 of 9 
==17186== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17186== by 0x400670: dequeue_push_front (dequeue.c:12) 
==17186== by 0x400A1D: main (main.c:21) 
==17186== 
==17186== 144 (24 direct, 120 indirect) bytes in 1 blocks are definitely lost in loss record 9 of 9 
==17186== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17186== by 0x400670: dequeue_push_front (dequeue.c:12) 
==17186== by 0x400BA3: main (main.c:48) 
==17186== 
==17186== LEAK SUMMARY: 
==17186== definitely lost: 48 bytes in 2 blocks 
==17186== indirectly lost: 168 bytes in 7 blocks 
==17186==  possibly lost: 0 bytes in 0 blocks 
==17186== still reachable: 0 bytes in 0 blocks 
==17186==   suppressed: 0 bytes in 0 blocks 
==17186== 
==17186== For counts of detected and suppressed errors, rerun with: -v 
==17186== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) 
+0

Почему вы оба выдаете адрес через '* dq' и освобождаете его в конце функции? – aschepler

+0

Я знаю, что бесплатно плохо, но если я прокомментирую это, тогда я получаю эти утечки памяти. – twistedhat

+0

'free' is ** not ** bad. Это то, что вы должны сделать, чтобы очистить себя. Это просто нужно сделать правильно. – dbush

ответ

2

В этой функции не требуется free(temp).

Эта функция выделяет temp в куче, используя malloc, тогда узел помещается в список. Если вы free() памяти, которую вы только что выделили, вы остаетесь с узлом в списке, который указывает на недопустимую память. Ссылка на этот узел приводит к неопределенному поведению, которое в этом случае проявляется в дампе ядра.

Правильное время для звонка free() - это когда узел удален из списка.

Что касается утечки памяти, это происходит в блоке else.

Вы размещаете temp в конце списка, но тогда вы перезаписать голову списка с temp, так что ваша единственная ссылка на остальной части списка в prev указатель temp. Однако, так как это теперь ваша новая голова, вы, вероятно, не потрудитесь смотреть на prev при очистке. Таким образом, у вас есть утечка памяти.

Чтобы устранить утечку, избавиться от присвоения *dq:

... 
else { 
    while (copy->next != NULL) { 
     copy = copy->next; 
    } 

    temp->prev = copy; 
    temp->next = NULL; 
    copy->next = temp; 
} 
... 
+0

У меня есть функция destroy, которая перемещается к узлам и удаляет их, но все равно получает утечки памяти, и valgrind сообщает мне об этом – twistedhat

+0

'== 17186 == 72 (24 прямых, 48 косвенных) байта в 1 блоке определенно потеряны в записи потерь 8 из 9 == 17186 == at 0x4C2AB80: malloc (в/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.так) == 17186 == 0x400670: dequeue_push_front (dequeue.c: 12) == 17186 == by 0x400A1D: main (main.c: 21) == 17186 == ' – twistedhat

+0

@twistedhat Смотрите мое редактирование. – dbush

2

Вы звоните free(temp), но продолжают использовать значение temp в линиях

(*dq) = temp; 

и

copy->next = temp; 

Не звоните free(temp). Обязательно освободите всю память в вызывающей функции, пройдя связанный список и вызовите free на всех узлах.

Доступ к памяти после free d является причиной неопределенного поведения.

Кстати, второй раз, когда вы используете

(*dq) = temp; 

приводит к утечкам памяти. Удалите эту строку.

Смежные вопросы