C语言链表实现故障求助:add_tail崩溃与菜单输入异常
C语言链表程序问题排查与修复
问题1:调用add_tail后程序卡死终止
原因
add_tail函数存在无限循环逻辑错误:
- 遍历链表时直接修改传入的
head指针,找到最后一个节点并添加新节点后,循环未终止,会继续遍历到新节点; - 新节点的
next为NULL,再次进入循环时会重复执行添加节点的逻辑,导致无限创建节点,耗尽内存后被系统终止; - 同时函数逻辑错误:空链表时直接返回NULL,无法添加第一个节点。
修复后的add_tail函数
struct node_t * add_tail(struct node_t * head, int value) { struct node_t * new_node = create_node(value); // 空链表时,新节点作为头节点返回 if (head == NULL) { return new_node; } // 使用临时指针遍历,不修改原head struct node_t * tmp = head; while (tmp->next != NULL) { tmp = tmp->next; } tmp->next = new_node; // 返回原头指针,添加尾部不改变头节点 return head; }
问题2:主菜单循环异常,跳过用户输入
原因
使用scanf("%c", &choice)读取字符时,会读取上一次输入(比如输入数字后按回车)留下的换行符,导致第二次循环时choice被赋值为换行符,触发default分支,表现为菜单重复打印且跳过输入。
修复方法
在读取字符时,添加空格跳过所有空白字符(包括换行、空格等),修改主函数中的scanf语句:
// 原代码 scanf("%c", &choice); // 修改为 scanf(" %c", &choice);
其他明显代码问题修复建议
- is_empty函数返回值逻辑优化
原函数返回0表示空链表,1表示非空,调整为符合常规的逻辑:
int is_empty(struct node_t * head) { // 返回1表示空,0表示非空 return head == NULL ? 1 : 0; }
同时主函数中对应判断逻辑同步修改:
// 原代码 if(is_empty(head) == 0){ printf("The list is empty!\n"); } else if(is_empty(head) == 1){ printf("The list is not empty!\n"); } // 修改为 if(is_empty(head) == 1){ printf("The list is empty!\n"); } else { printf("The list is not empty!\n"); }
- get_value函数未正确赋值
原主函数中调用get_value后未将返回值赋值给value,导致判断错误:
// 原代码 printf("Please enter the index for which you would like to know the value: "); scanf("%d", &index); if(value == FAIL){ printf("Error. Try again\n"); } else{ printf("The value of the element at index %d is %d\n", index, value); } // 修改为 printf("Please enter the index for which you would like to know the value: "); scanf("%d", &index); value = get_value(head, index); // 新增赋值语句 if(value == FAIL){ printf("Error. Try again\n"); } else{ printf("The value of the element at index %d is %d\n", index, value); }
- replace_val函数错误释放节点
原函数中修改节点值后错误释放当前节点,导致链表断裂,直接删除free(head)语句:
// 原代码 if (index == 0){ tmp = head; tmp -> value = value; free(head); head = tmp; } // 修改为 if (index == 0){ head->value = value; }
- remove_val函数未处理头节点匹配的情况
原函数无法删除头节点是目标值的情况,修复后:
struct node_t * remove_val(struct node_t * head, int value) { if(head == NULL){ printf("Value cannot be found in an empty list. Try again\n"); return head; } // 处理头节点就是目标值的情况 if (head->value == value) { struct node_t * tmp = head; head = head->next; free(tmp); return head; } struct node_t * tmp = head; while(tmp->next != NULL){ if(tmp->next->value == value){ struct node_t * del_node = tmp->next; tmp->next = del_node->next; free(del_node); return head; } tmp = tmp->next; } printf("The value does not exist in the list. Try again\n"); return head; }
- delete_node函数逻辑错误修复
原函数处理index==1时的代码完全错误,修复后:
struct node_t * delete_node(struct node_t * head, int index) { if(index < 0){ printf("Index cannot be a negative number. Try again\n"); return head; } if(head == NULL){ printf("Cannot delete elements from an empty list. Try again\n"); return head; } // 删除头节点 if (index == 0) { struct node_t * tmp = head; head = head->next; free(tmp); return head; } struct node_t * tmp = head; // 遍历到目标节点的前一个节点 for (int i = 0; tmp != NULL && i < index-1; i++) { tmp = tmp->next; } // 索引超出范围 if (tmp == NULL || tmp->next == NULL) { printf("The index is not found in the bounds of the list. Try again\n"); return head; } // 删除目标节点 struct node_t * del_node = tmp->next; tmp->next = del_node->next; free(del_node); return head; }
内容的提问来源于stack exchange,提问作者kei_cse_26
相关产品推荐
相关产品推荐

