использование free () в C - PullRequest
       8

использование free () в C

0 голосов
/ 20 апреля 2011

Я работаю над некоторыми упражнениями C (новичок). У меня возникла небольшая проблема.Мне дали очередь «первый пришел - первый вышел» и сказали изменить функцию удаления на FILO.

Это прекрасно работает, когда я опускаю free ((void *) p);строка внутри цикла while, я взял эту строку из предыдущего метода.Может кто-нибудь сказать мне, почему это не работает, когда эта линия там?Я думаю, я не могу удалить его из-за утечек памяти?

/* remove next Item from queue, placing it in the 2nd argument;
* return 1/0 if successful/queue empty */

int q_remove(Queue *q, Item i) {
struct q_element *p;
if (q->head == NULL)
    return 0;
if(q->head==q->tail){
    p=q->head;
    q->head=NULL;
    q->tail=NULL;
    memcpy(i, p->value, q->size);
    free(p->value);
    free((void *) p);
    return 1;
}
p=q->head;
while(p != NULL){
    if(p->next==q->tail){
        memcpy(i, p->next->value, q->size);
        free(p->next->value);
        q->tail=p;
        q->tail->next=NULL;
        free((void *) p);
        return 1;


    }
    p=p->next;

}

return 0;
}

Ответы [ 3 ]

2 голосов
/ 20 апреля 2011

проблема в том, что вы указываете на что-то, что вы собираетесь освободить в следующей строке кода:

q->tail=p;
...
free((void *) p);

теперь, когда вы попытаетесь получить доступ к q-> tail, вы получите сообщение об ошибке, поскольку вы уже освободили эту память.

вы должны попробовать free p-> next вместо p (поскольку p-> next - последний элемент в вашей очереди - так что это тот, который вы хотите удалить)

удачи:)

1 голос
/ 20 апреля 2011

Строки:

q->tail->next=NULL;
free((void *) p); 

... должны быть, вероятно,

free( free( (void *) p->next );
p->next=NULL;

, потому что вы не пытаетесь освободить 'p' (это ваш новый 'хвост'), но элемент p-> рядом с которым ты был старым хвостом.Установите указатель на нуль после того, как вы его освободите.Значение q-> tail уже указывает на «p», и после этого нельзя освобождать «p», поскольку «p-> next» - это то, что вы пытаетесь удалить.

Этоможет быть и так.

Кроме того, мне лично не нравится, как вы определили 'Item' как пустоту * где-то, это выглядит странно, потому что 'Item' выглядит как переменная, передаваемая по значениюв стеке.

Кев

0 голосов
/ 20 апреля 2011

Мне кажется, что вы освобождаете p, но перед тем, как сделать это, вы присваиваете значение p q->tail, оставляя q->tail, указывающее на недопустимую память, которая скоро станет недействительной. Вы фактически освобождаете q->tail.

Где-то еще, я подозреваю, вы используете q->tail, что заставит вашу ОС кричать и убивать вашу программу, как Аид на роликах.

...