从链表中删除项目时出现分段错误



我想创建一个程序,你输入'+word',它会添加单词,当你输入'-word'时,它会从链表中取出单词。

插入这个词对我来说很好,但删除它会导致分割错误。我不确定问题出在哪里。另外,有没有一种方法可以让你得到分段错误在哪里的提示?

void
remove_from_list(struct linked_list *list, char *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) {
        list->head = list->head->next;
    } else {
        previous_node->next = current_node->next;
    }
    free(current_node);
    if (list->tail == current_node)
        list->tail = previous_node;
}
int
main(void)
{
    struct linked_list list = { .head = NULL, .tail = NULL };
    char word[50];
    do {
        printf("Enter string: ");
        fgets(word, 50, stdin);
        if (word[0] == '+')
            add_to_list(&list, word);
        else if (word[0] == '-')
            remove_from_list(&list, word);
    } while (word[0] != 'n');
    print_list_rec(&list);
    free_list(&list);
    return 0;
}

出现分段错误的主要原因是在试图删除时没有处理列表中没有数据的情况。

if (previous_node == NULL) { 
    list->head = list->head->next;
} else { // ------------------------- If at the end of the list you go in here
    previous_node->next = current_node->next;
}

current_nodeNull,因此current_node->next为segg故障。

你到列表末尾的原因是因为你没有正确地比较字符串的数据。使用strcmp() @this建议正确比较。但是你应该处理列表中没有数据的情况。


你可以在while循环和第一个if语句之间添加一个check - in,这将处理一个空列表和不在列表中的数据

if(current_node == NULL) // Empty list or wasn't found
    return;

另一个注意:

你释放current_node,然后检查它是否是尾部。

if (list->tail == current_node)
    list->tail = previous_node;
free(current_node);

循环到链表的末尾,然后在这里解引用NULL指针

} else {
    previous_node->next = current_node->next;
}

这是因为你的比较实际上并没有比较数据;

 if (current_node->data == data) {

你永远不会从if语句中得到一个真正的结果

如果要比较字符串,请使用strcmp()

在其他人所说的内容之上,如果列表为空,则此代码将导致分割:

if (previous_node == NULL) {
    list->head = list->head->next;
}

如果没有插入函数的代码,很难说它哪里出错了,因为删除的步骤看起来很好。然而,可能有一些错误的插入,由于这是不工作。

但是在你的代码中有一个问题,其中如果你试图删除一个不存在的节点,你仍然会最终删除最后一个节点。您需要在while循环中断之前设置一个标志,然后仅在标志为true时删除该节点。

函数应该如下所示

void
remove_from_list( struct linked_list *list, char *data )
{
    struct node *current_node = list->head;
    struct node *previous_node = NULL;
    while ( current_node != NULL && strcmp( current_node->data, data ) != 0 ) 
    {
        previous_node = current_node;
        current_node = current_node->next;
    }
    if ( current_node != NULL ) 
    {
        if ( previous_node != NULL ) 
            previous_node->next = current_node->next;
        else
            head = head->next; 
        if ( list->tail == current_node )
            list->tail = previous_node;
        free( current_node->data );
        free( current_node );
    }
}

我也会存储字符串没有前导+或-。在这种情况下,main中的if语句看起来像

    if ( word[0] == '+' )
        add_to_list( &list, word + 1 );
    else if ( word[0] == '-' )
        remove_from_list( &list, word + 1 );

否则你将永远找不到一个添加了加号的字符串来从列表中删除它。

相关内容

  • 没有找到相关文章

最新更新