从链表中删除项目会导致分段错误

时间:2014-06-24 20:04:02

标签: c linked-list segmentation-fault singly-linked-list

我有一个问题,我试图从链表中删除一个条目,但无论我在哪里尝试从头部,中间或尾部删除项目,都会导致分段错误。我不确定问题出在哪里。

    void
    add_to_list(struct linked_list *list, int x)
    {
        struct node *n = malloc(sizeof *n);
        n->data = x;
        n->next = NULL;
        if (list->head == NULL)
            list->head = n;
        if (list->tail != NULL)
            list->tail->next = n;
        list->tail = n;
    }
    void
    remove_from_list(struct linked_list *list, int position)
    {
        struct node *current_node = list->head;
        struct node *previous_node = NULL;
        int i;
        for (i = 0; i < position; i++) {
            previous_node = current_node;
            current_node = current_node->next;
        }
        if (position == 0) {    // removing the head means we have to
                        // update the head pointer
            list->head = list->head->next;
        } else {
            previous_node->next = current_node->next;
        }
        free(current_node);
        if (list->tail == current_node) // remove the last element means
                    // updating the tail pointer
            list->tail = previous_node;
    }

    int
    main(void)
    {
        struct linked_list list = { .head = NULL, .tail = NULL };
        add_to_list(&list, 'h');
        add_to_list(&list, 'e');
        add_to_list(&list, 'l');
            add_to_list(&list, 'l');
            add_to_list(&list, 'o');
        remove_from_list(&list, 'e');
        add_to_list(&list, 's');
        print_list_rec(&list);  // print_nodes_rec(list.head)
        free_list(&list);
        return 0;
    }

2 个答案:

答案 0 :(得分:2)

电话

remove_from_list(&list, 'e');

'e'指定为列表中的位置。 'e'的ascii值为101;你在列表中有5个项目。

remove_from_list遍历列表position次,而不检查它是否已到达终点。

您需要将此更改为让调用方传递要删除的索引,或者更好地将第二个参数更改为项值以搜索并修改for中的remove_from_list循环}当它找到这个值时退出。

void remove_from_list(struct linked_list *list, int data)
{
    struct node *current_node = list->head;
    struct node *previous_node = NULL;
    while (current_node != NULL) {
        if (current_node->data == data) {
            break;
        }
        previous_node = current_node;
        current_node = current_node->next;
    }
    if (previous_node == NULL) { // removing the head means we have to

在任何一种情况下,如果remove_from_list同时防止阅读超出其列表的末尾,它会更安全

答案 1 :(得分:0)

您似乎没有检查是否已经到达列表的末尾,并且您可能正在尝试释放NULL指针。