【问题标题】:Why does my linked list code produce a segmentation fault when deleting the head node?为什么我的链表代码在删除头节点时会产生分段错误?
【发布时间】:2016-10-24 15:54:17
【问题描述】:

从链表的头部删除时,我似乎遇到了段错误。返回的头部为 NULL。它也可能是在其他地方删除的东西,但是 printf 语句被打印了,所以我相信它与没有正确重置磁头有关。它进行一次传递并从头部删除并工作,但不是第二次。

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)
    }
}

【问题讨论】:

  • 我看不到函数在哪里结束。缺少一个结束“}”。添加它。
  • 你已经将一个指针填充到指向头的指针,不需要也返回它。
  • @MichaelEhnes——我意识到我最初的答案是使用与您的代码略有不同的结构设计。我已经解决了这个问题,并添加了你的代码的修改版本。

标签: c linked-list segmentation-fault nodes


【解决方案1】:

您的delete_it() 函数存在许多问题。它不处理 NULL 指针输入,不以连贯的方式遍历列表,不处理遍历列表时可能出现的所有 NULL 指针情况,包含一个似乎没有用的变量 i ,逻辑一团糟。它可以挽救工作:

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;
}

但是,你不应该挽救它。你的delete_it() 函数比它需要的更复杂。我会像你一样返回一个指向列表头部的指针,但是不需要将双指针传递给头部。此外,通过将prev 初始化为NULL 而不是head 并简化逻辑,您可以大大简化代码:

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;
}

【讨论】:

    猜你喜欢
    • 2021-02-18
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 2021-07-10
    • 2016-02-08
    • 1970-01-01
    • 2020-04-19
    相关资源
    最近更新 更多