twistedhat twistedhat - 1 month ago 17
C Question

Deleting Linked LIst in C

I just stuck with the problem couple of hours, trying to find where my code breaks. I know how to delete linked list but something doesn't work.

First it is a very simple struct with a dataype of int and 2 struct *next and *prev.

struct _list_{
struct _list_ *next;
struct _list_ *prev;
float distance;
}


Now i am making a push_front function and it works great. I get the result that i am looking for. But now i am making pop_front function and something is missing.

The function should return the distance and then remove that list from the linked list but i can't make it do it.

here is the code that i wrote

int pop_front(list** header)
{
float number = (*header)->data;
list *head = *header;
list *remove = head;

// This should check if the pointer is pointing at the first element
while (head->prev != NULL) {
head = head->prev;
}

if (head) {
head = head->next;
free(remove);
remove = head;
remove->prev = NULL;
//if i remove the code below then i get this error
//*** Error in `./double_ended_queue.out': double free or
//corruption (fasttop): 0x0000000001d5a050 ***
//Pop up: 3 pointer: 3 Aborted (core dumped)
*header = *remove;
//And with this code i get a Segmentation fault (core dumped
return number;
}
return 0;
}


Any help would be great, thank you.

P.S. checked all the linked list question here and none helped.

Answer

Where are you all getting this homework from? The API sux. Here, someone else did have almost the same homework (link pointing to my answer, which has many issues left): Pointer Dequeue - pointer training

Anyways:

Do you want to return int or float? The element data is type float, your variable "number" too, but your function returns int.

int pop_front(list** header)
{
  float number = (*header)->data;

so, here you get the value of the element you're trying to remove, but then ...

  list *head = *header;
  list *remove = head;

  // This should check if the pointer is pointing at the first element
  while (head->prev != NULL) {
    head = head->prev;
  }

... you actually SEARCH for the element to remove.

Obviously, you have to do it the other way round:

int pop_front(list** header)
{
    list * head = *header;
    while (head->prev) head = head->prev;

now, you should check, weather you need to adjust the *header pointer (and do it right away):

    if (*header == head) {
        *header = head->next;
    }

the only thing to do now is to remove the object from the list, get it's value and free it's memory before return.

    head->next->prev = NULL;
    float retval = head->data;
    free(head);
    return retval;
}

As exercise left to you: Make sure, that an empty list doesn't crash ;)

/edit: This will also crash for removal of the last element, so you have two exercises left ;)

Comments