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

CS50 Speller程序出现Segmentation Fault,请求定位错误原因

CS50 Speller 段错误排查

核心错误原因

你的代码里直接触发段错误的是load函数中的char *word = NULL;:

  • fscanf(infile, "%s", word)需要一个有效的内存地址来存储读取的单词,但你将word初始化为NULL,未分配任何内存空间。当fscanf尝试往空指针指向的区域写入数据时,直接引发内存访问违规,也就是段错误。

附带问题及修复方案

  1. 哈希表节点覆盖问题
    当前代码处理哈希值相同的单词时,会直接用新节点覆盖table[hash_value]的旧值,导致之前的节点内存泄漏,且同一个哈希桶仅能保留最后一个单词。正确做法是用链表串联同哈希值的节点:
    首先修改node结构体,添加链表指针:

    typedef struct node
    {
        char word[LENGTH + 1];
        struct node *next; // 新增链表指针
    } node;
    

    然后在load函数中替换table[hash_value] = new_node;为:

    new_node->next = table[hash_value]; // 先指向当前桶的头节点
    table[hash_value] = new_node;       // 将新节点设为桶的头节点
    
  2. check函数逻辑错误
    当前check仅检查哈希桶是否为空,未遍历链表查找具体单词,且未实现大小写不敏感的检查要求。修正后的逻辑:

    bool check(const char *word)
    {
        char lower_word[LENGTH + 1];
        // 将输入单词转为小写
        for (int i = 0; word[i] != '\0'; i++)
        {
            lower_word[i] = tolower(word[i]);
        }
        lower_word[strlen(word)] = '\0';
    
        unsigned int hash_val = hash(lower_word);
        node *cursor = table[hash_val];
        // 遍历链表查找单词
        while (cursor != NULL)
        {
            if (strcmp(lower_word, cursor->word) == 0)
            {
                return true;
            }
            cursor = cursor->next;
        }
        return false;
    }
    
  3. hash函数的溢出与大小写问题
    原哈希计算hash_value = word[i] * hash_value易引发无符号整数溢出,且未处理大小写导致同一单词大小写不同哈希值不同。优化后的哈希函数:

    unsigned int hash(const char *word)
    {
        unsigned int hash_value = 0;
        for (int i = 0; word[i] != '\0'; i++)
        {
            hash_value = hash_value * 31 + tolower(word[i]); // 用31作为乘数,转小写保证哈希不区分大小写
        }
        return hash_value % N;
    }
    

修复段错误的关键步骤

将load函数中的char *word = NULL;替换为:

char word[LENGTH + 1]; // 直接分配足够存储最长单词的栈内存,LENGTH为CS50定义的常量

这样fscanf就有了合法的内存地址存储读取的单词,解决段错误的核心问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 16:46:29