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

C语言链表中fgets()覆盖结构体部分数据的问题求助

C语言链表学生信息被覆盖的问题解决

问题根因

你这问题说白了就是所有链表节点的字符串都共用了同一块内存。比如你可能定义了一个全局或者局部的字符数组当输入缓冲区,然后直接把这个数组的地址塞给结构体里的字符串指针,没给每个节点单独开内存存自己的字符串。这样每次调用fgets()往缓冲区里写新内容,之前节点存的指针指向的还是这块缓冲区,自然就被覆盖了。

解决办法

  • 给每个节点的字符串单独分配内存
    读入学生信息后,别直接把缓冲区地址赋值给结构体,用malloc申请一块新内存,再把缓冲区里的内容复制过去:

    // 拿姓名字段举例子
    char input_buf[100];
    fgets(input_buf, sizeof(input_buf), stdin);
    // 先去掉fgets自带的换行符
    input_buf[strcspn(input_buf, "\n")] = '\0';
    // 申请内存,长度要包含字符串结束符'\0'
    new_node->name = malloc(strlen(input_buf) + 1);
    if (new_node->name == NULL) {
        // 内存分配失败的处理,比如报错退出
        perror("内存分配失败");
        exit(1);
    }
    // 把缓冲区内容复制到新内存里
    strcpy(new_node->name, input_buf);
    
  • 别犯直接赋值指针的低级错误
    绝对不能这么写:

    new_node->name = input_buf; // 大错!所有节点的name都指向同一个input_buf
    

    这种写法等于所有节点的字符串都指着同一段内存,后面输入的内容必然覆盖前面的。

  • 验证修改效果
    改完可以打印每个节点字符串的内存地址(printf("%p\n", node->name);),每个节点的地址应该不一样,要是都一样说明还没改对。

额外提醒

  • 销毁链表的时候,要先释放每个节点里的字符串内存,再释放节点本身,不然会出现内存泄漏。
  • fgets()会把换行符读进缓冲区,记得用strcspn()去掉,不然存的字符串里会带换行符,显示时容易出问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:53:19