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

C语言递归实现链表添加元素时出现段错误问题求助

问题分析与修复方案

你的代码存在多个触发段错误和异常行为的问题,逐一拆解并给出修复方案:

1. 野指针引发内存非法访问

main函数中char* name;仅声明了指针但未分配内存,直接用scanf("%10s", name);会向随机内存地址写入数据,这是段错误的核心诱因之一。

修复:为name分配足够内存,比如:

char name[11]; // 适配%10s的输入长度,额外1位存字符串终止符

2. 输入格式错误导致数据读取异常

  • 读取symbol时,scanf("%2c", &symbol);会读取前一次输入残留的换行符,导致symbol被错误赋值。需在格式符前加空格跳过空白字符:scanf(" %c", &symbol);(单个字符无需长度限制)
  • weight是double类型,scanf需用%lf格式符,而非%f(%f用于float类型),否则会导致数据读取错误。

3. 函数逻辑与命名不符

add_to_front实际是向链表尾部添加元素,而非头部,函数名易造成误解。若需尾部添加,建议重命名为add_to_tail;若要实现头部添加,逻辑需调整(头部添加无需递归,直接创建新节点指向原头节点即可)。

4. 链表节点name的浅拷贝问题

create_list中head->name = name;是直接赋值指针,所有节点的name会指向同一块内存(main中的name数组),后续输入会覆盖之前节点的name值。若要每个节点保存独立的name,需分配内存并拷贝字符串:

head->name = malloc(strlen(name) + 1);
strcpy(head->name, name);

注意:销毁链表时需释放name的内存,避免内存泄漏。

5. 冗余的内存分配

create_list中malloc(sizeof(list) + 1000);完全多余,sizeof(list)已包含结构体所有成员的内存大小,改为malloc(sizeof(list));即可。


修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct list
{
    char* name;
    char symbol;
    double weight;
    struct list *next;
} list;

list* create_list(char* name, char symbol, double weight)
{
    list* node = malloc(sizeof(list));
    if (!node) { // 检查内存分配是否成功
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }
    // 为name分配独立内存并拷贝内容
    node->name = malloc(strlen(name) + 1);
    if (!node->name) {
        perror("malloc for name failed");
        free(node);
        exit(EXIT_FAILURE);
    }
    strcpy(node->name, name);
    node->symbol = symbol;
    node->weight = weight;
    node->next = NULL;
    return node;
}

// 重命名为add_to_tail,明确功能
void add_to_tail(char* name, char symbol, double weight, list* h)
{
    if (h->next == NULL)
    {
        h->next = create_list(name, symbol, weight);
    }
    else
    {
        add_to_tail(name, symbol, weight, h->next);
    }
}

// 销毁链表,避免内存泄漏
void destroy_list(list* head) {
    list* temp;
    while (head) {
        temp = head;
        head = head->next;
        free(temp->name);
        free(temp);
    }
}

int main(void)
{
    char name[11];
    char symbol;
    double weight;

    printf("Enter element's name: ");
    scanf("%10s", name);
    printf("Enter element's symbol: ");
    scanf(" %c", &symbol); // 跳过空白字符
    printf("Enter element's weight: ");
    scanf("%lf", &weight); // 用%lf读取double类型
    list* head = create_list(name, symbol, weight);

    for (int i = 0; i < 3; i++)
    {
        printf("Enter element's name: ");
        scanf("%10s", name);
        printf("Enter element's symbol: ");
        scanf(" %c", &symbol);
        printf("Enter element's weight: ");
        scanf("%lf", &weight);
        add_to_tail(name, symbol, weight, head);
    }

    // 打印链表验证结果
    list* current = head;
    while (current) {
        printf("Name: %s, Symbol: %c, Weight: %.2lf\n", current->name, current->symbol, current->weight);
        current = current->next;
    }

    destroy_list(head); // 释放所有内存
    return 0;
}

内容的提问来源于stack exchange,提问作者AleksandrZhukovin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:10:21