删除节点时无限循环

时间:2018-02-07 20:06:02

标签: c linked-list nodes

删除节点时,我得到一个无限循环。

以下是删除节点的位置:

llist *modify_sorted_total(gymnast_info *ginfo, llist *head) {

    llist *accu = head;
    int pos = 0;

    while (accu) {
        if (strcasecmp(ginfo->lastname, accu->g->lastname) == 0 &&
            strcasecmp(ginfo->firstname, accu->g->firstname) == 0) {
            remove_node(accu, pos);
            add_sorted_total(ginfo, head);
            return head;
        }
        pos++;
        accu = accu->next;
    }
    return NULL;
}

这是我的删除节点功能:

void remove_node(llist *head, int pos) {
    int i;
    llist* list = head;
    for (i = 0 ; i < pos ; i++)
        list = list->next;

    llist *temp = list;
    if (pos == 0) {
        head = temp->next;
        free(temp);
        return;
    } else if (pos > 0 && list->next) {
        temp = list->next->next;
        free(list->next->next);
        free(list->next);
        list->next = temp;
        free(temp);
        return;
    } else if (pos > 0 && !list->next) {
        list = head;
        for (i = 0 ; i < pos - 1 ; i++)
            list = list->next;
        free(list);
        list->next = NULL;
        return;
    }
}

所以这就是我运行测试的方式。列表已创建,这当然有效。:

fprintf(stdout, "\nEyeball tests starting!\n\nTesting create_gymnast:\n\n");
    float test_scores1[NUM_EVENTS] = {8.7, 8.5, 8.4, 8.2};
    float test_scores2[NUM_EVENTS] = {5.2, 5.7, 5.4, 5.6};
    float test_scores3[NUM_EVENTS] = {3.8, 3.7, 3.6, 3.7};
    //float test_scores4[NUM_EVENTS] = {1.5, 1.3, 1.4, 1.4};                                                 

    gymnast_info *adam = create_gymnast("Adam",
                                "Fonseca", USA, test_scores1);

    gymnast_info *jersey = create_gymnast("Jersey",
                                "Fonseca", USA, test_scores2);

    gymnast_info *joshua = create_gymnast("Joshua",
                               "ZZZ", CHINA, test_scores3);

    gymnast_info *zach = create_gymnast("Zachary",
                               "middle", MEXICO, test_scores3);

llist *test3 = (llist *)malloc(sizeof(llist));
    test3->g = joshua;
    test3->next = NULL;

    fprintf(stdout, "Jersey should be added to the end:\n\n");
    print_list(add_sorted_total(jersey, test3), stdout);
    fprintf(stdout, "\nZachary should be added to the middle:\n\n");
    print_list(add_sorted_total(zach, test3), stdout);
    fprintf(stdout, "\nAdam should be added to the end:\n\n");
    print_list(add_sorted_total(adam, test3), stdout);

print_list(modify_sorted_total(joshua, test3), stdout);
约书亚被无限地打印出来。当我尝试在gdb中使用ctrl-c时,它说它在“??”。任何人都知道发生了什么事?

1 个答案:

答案 0 :(得分:1)

一个大问题:

    temp = list->next->next;
    free(list->next->next);
    free(list->next);
    list->next = temp;
    free(temp);

临时指向列表 - &gt; next-&gt;接下来,您已经在其上调用了free。在同一位置双重免费是未定义的行为。任何事情都可能发生。

即使有1次免费,也会失败,因为您已将已释放的位置(temp)指定为list->next

我相信你想删除&amp;免费的一个元素。该代码应该足够了:

temp = list->next->next;
free(list->next);
list->next = temp;

它将list->next->next保存在temp中(因为在list->next free之后,再过它是不合法的),然后将其分配给现在已释放list->next:您只是缩短了链接列表而没有内存泄漏且没有未定义的行为。

最后一种情况(删除最后一个元素)也是一个问题。您应该记住前一个元素,将next设置为NULL

然后这样做:

    free(list);
    list->next = NULL;

list->next将已删除的元素的下一个元素设置为NULL:非法&amp;你正在释放错误的元素。你的意思是:

free(list->next);
list->next = NULL;