我尝试创建程序,您输入' + 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;
}
答案 0 :(得分:1)
循环到链接列表的末尾,然后继续在此处取消引用NULL指针
} else {
previous_node->next = current_node->next;
}
这是因为您的比较并未实际比较数据;
if (current_node->data == data) {
你永远不会从if语句中得到真实的结果。
如果要比较字符串,请使用strcmp()。
答案 1 :(得分:1)
您遇到seg错误的主要原因是您在尝试删除时没有处理列表中没有数据的情况。
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_node
为Null
,因此current_node->next
会出现错误。
您到列表末尾的原因是因为您没有正确比较字符串的数据。使用strcmp()
之类的@this建议进行正确比较。但是你应该处理列表中没有数据的情况。
您可以在while循环和first if语句之间添加一个检查,这将处理一个空列表和不在列表中的数据 -
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);
答案 2 :(得分:0)
除了其他人所说的,如果列表为空,此代码将导致分段:
if (previous_node == NULL) {
list->head = list->head->next;
}
答案 3 :(得分:0)
如果没有插入功能的代码,很难说出错了,因为删除的步骤会很好。但是,插入可能会出现问题,因为这样做不起作用。
但是您的代码中存在问题,如果您尝试删除不存在的节点,您仍将最终删除最后一个节点。您需要在while循环中断时设置一个标志,然后仅在flag为true时删除该节点。
答案 4 :(得分:0)
该功能应该采用以下方式
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 );
否则,您永远不会找到添加了加号的字符串,以便将其从列表中删除。