简体   繁体   中英

Why does my linked list code produce a segmentation fault when deleting the head node?

I seem to get a segfault when deleting from the head of the linked list. The head that gets returned comes out NULL. It could also be something deleting somewhere else however, the printf statement gets printed so I believe that it has something to do with not resetting the head properly. It makes one pass and deletes from the head and works, but not the second time.

node_t* delete_it(node_t** head, int id){

    node_t* temp;
    node_t* prev = (*head);
    node_t* current = (*head);
    int i = 0;

    //checking to see if the head has the id
    if((*head)->player.player_ID == id){

        printf("removing from the head\n");
        temp = (*head);
        (*head) = (*head)->next;
        free(temp);
        return (*head);

    }

    //moving through finding the id
    while(current->player.player_ID != id){

        if(i > 0){

            prev = prev->next;

        }
        //keeps prev pointer the one before current
        i++;
        current = current->next;

        //checking for tail
        if(current->next == NULL && current->player.player_ID == id){
            temp = current;
            free(temp);
            return (*head);

        }

        //removing the node form somewhere inbetween head and tail
        if(current->player.player_ID == id){

            temp = current;
            prev->next = current->next;
            free(temp);
            return (*head);

        }

        return(*head)
    }
}

There are many problems with your delete_it() function. It doesn't handle NULL pointer inputs, doesn't step through the list in a coherent way, doesn't handle all cases of NULL pointers that might arise in traversing the list, contains a variable i that seems to serve no purpose, and the logic is a mess. It can be salvaged to work:

node_t* delete_it_2(node_t** head, int id){

    node_t* temp;
    node_t* prev = (*head);
    node_t* current = (*head);
    int i = 0;

    //checking to see if the head has the id
    if(*head != NULL && (*head)->player.player_ID == id){

        printf("removing from the head\n");
        temp = (*head);
        (*head) = (*head)->next;
        free(temp);
        return (*head);

    }

    //moving through finding the id
    while(current != NULL && current->player.player_ID != id){
        prev = current;
        current = current->next;
    }

    if (current == NULL)
        return *head;

    //checking for tail
    if(current->next == NULL && current->player.player_ID == id){
        free(current);
        prev->next = NULL;
        return (*head);
        }

    //removing the node form somewhere inbetween head and tail
    if(current->player.player_ID == id){

        temp = current;
        prev->next = current->next;
        free(temp);
        return (*head);
    }

    return *head;
}

But, you shouldn't salvage it. Your delete_it() function is more complicated than it needs to be. I would return a pointer to the head of the list, as you do, but then there is no need to pass a double pointer to the head. Also, by initializing prev to NULL instead of to head and streamlining the logic, you can substantially simplify the code:

node_t * delete_it(node_t *head, int id){

    node_t *temp;
    node_t *prev = NULL;
    node_t *current = head;

    while (current != NULL && current->player.player_ID != id) {
        prev = current;
        current = current->next;
    }

    if (current != NULL) {
        if (prev != NULL) {
            temp = current;
            prev->next = current->next;
        } else {
            temp = head;
            head = head->next;
        }
        free(temp);
    }

    return head;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM