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

链表批量添加字段触发Segmentation Fault错误排查求助

段错误原因分析与修复方案

核心问题点

  • 循环边界错误:原代码while (id <= count)会多执行一次循环(id从0到count共count+1次),当id等于count时,newContact被设为NULL,后续执行newContact->next = *head时,访问空指针的成员直接触发段错误。
  • 非法指针修改:else分支里的newContact = newContact->next;是致命错误——刚malloc的节点next是未初始化的随机值,将newContact指向该垃圾地址后,所有后续操作都是非法内存访问。
  • 链表插入逻辑混乱:原代码没有正确维护链表指针关系,用被错误修改的newContact操作链表,完全违背了链表节点插入的基本逻辑。
  • 遍历打印逻辑错误:while (currentNode->next != NULL)会跳过链表最后一个节点,应该判断currentNode本身是否为NULL。

修复后的代码

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

// 假设Contact结构体定义如下
typedef struct Contact {
    char *fieldsName;
    char fieldsValue[30];
    struct Contact *next;
} Contact;

// 实现getString函数(读取用户输入到缓冲区)
void getString(char *buf, int size, const char *prompt) {
    printf("Enter %s: ", prompt);
    fgets(buf, size, stdin);
    buf[strcspn(buf, "\n")] = '\0'; // 去除换行符
}

void addContact(Contact **head)
{
    Contact *newContact; 
    Contact *currentNode;
    char listFieldsName[][30] = {"First Name", "Middle Name", "Last Name", "Company", "Phone", "Email", "Address", "Birthday", "Website", "Note"};
    int count = sizeof(listFieldsName) / sizeof(listFieldsName[0]);
    int id = 0;

    // 修正循环边界,只处理定义的字段
    while (id < count)
    {
        // 为每个字段分配新节点
        newContact = (Contact *)malloc(sizeof(Contact));
        if (newContact == NULL) {
            perror("malloc failed");
            return; // 内存分配失败时退出
        }

        // 绑定字段名(若需持久化可改用strdup分配内存)
        newContact->fieldsName = listFieldsName[id];
        // 获取用户输入的字段值
        getString(newContact->fieldsValue, 30, listFieldsName[id]);
        // 标准链表头部插入逻辑
        newContact->next = *head;
        *head = newContact;

        id++;
    }

    // 遍历打印所有节点
    currentNode = *head;
    while (currentNode != NULL)
    {
        printf("%s: %s\n", currentNode->fieldsName, currentNode->fieldsValue);
        currentNode = currentNode->next;
    }
}

// 测试主函数
int main() {
    Contact *head = NULL;
    addContact(&head);
    // 注意:后续需手动释放链表内存避免泄漏
    return 0;
}

关键修改说明

  1. 修正循环边界,确保只处理预设的10个字段,避免进入空指针分支。
  2. 移除错误的指针赋值语句,保留newContact指向刚分配的有效节点。
  3. 采用标准的链表头部插入逻辑,正确维护链表指针关系。
  4. 修复遍历打印的判断条件,确保所有节点都被输出。
  5. 添加malloc失败的错误处理,避免内存分配失败后的非法操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:40:23