You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

其他明显代码问题修复建议

  1. 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");
}
  1. 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);
}
  1. replace_val函数错误释放节点
    原函数中修改节点值后错误释放当前节点,导致链表断裂,直接删除free(head)语句:
// 原代码
if (index == 0){
    tmp = head;
    tmp -> value = value;
    free(head);
    head = tmp;
}
// 修改为
if (index == 0){
    head->value = value;
}
  1. 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;
}
  1. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 11:42:38