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

CS50 speller.c加载函数中哈希表引发段错误求助

解决CS50 Speller作业中Load函数的段错误问题

核心错误原因

你遇到的段错误是因为全局哈希表数组table的元素未初始化就被解引用。全局指针数组默认初始化为NULL,但你的代码在load函数中直接执行table[hashnum]->next == NULL——对NULL指针进行->操作,直接触发内存访问错误(段错误)。


分步修复方案

1. 修正哈希表节点插入逻辑

把table的每个元素作为链表的头指针(而非指向一个头节点),插入节点时直接操作头指针:

// 替换原有的插入逻辑
hashnum = hash(dictword->word);

// 如果当前哈希桶为空,直接让头指针指向新节点
if (table[hashnum] == NULL)
{
    table[hashnum] = dictword;
    dictword->next = NULL;
}
// 否则把新节点插入链表头部(头插法)
else
{
    dictword->next = table[hashnum];
    table[hashnum] = dictword;
}

2. 修复单词读取的字符串终止问题

你的代码读取单词时没有添加字符串终止符'\0',会导致后续hash、strcasecmp操作读取垃圾数据甚至越界。修改读取单词的逻辑:

// 替换原有的单词读取循环
int tmpctr = 0;
char c;
// 读取字符直到换行、文件结束,或达到单词长度上限
while (fread(&c, sizeof(char), 1, dict) && c != '\n' && tmpctr < LENGTH)
{
    dictword->word[tmpctr++] = c;
}
// 添加字符串终止符,确保是合法C字符串
dictword->word[tmpctr] = '\0';

3. 修正其他函数的指针访问问题

  • check函数:原代码直接访问table[hashnum]->next,同样会在哈希桶为空时触发段错误,改为从表头开始遍历:
bool check(const char *word)
{
    int hashnum = hash(word);
    node *tmpnode = table[hashnum]; // 直接指向表头
    while (tmpnode != NULL)
    {
        if (strcasecmp(word, tmpnode->word) == 0)
        {
            return true;
        }
        tmpnode = tmpnode->next;
    }
    return false;
}
  • unload函数:原代码跳过了表头节点,改为从表头开始释放整个链表:
bool unload(void)
{
    for(int i = 0; i < N; i++)
    {
        freehash(table[i]);
    }
    return true;
}

void freehash(node* node)
{
    if (node == NULL) return; // 空链表直接返回
    freehash(node->next);
    free(node);
}

4. 修复load函数的其他小问题

  • 当fopen失败时,不要调用fclose(dict)(dict是NULL,fclose(NULL)是未定义行为):
if (dict == NULL)
{
    printf("\n\n Could not load dictionary.\n");
    return false;
}
  • malloc失败时,无需free(dictword)(dictword已经是NULL):
node *dictword = malloc(sizeof(node));
if (dictword == NULL)
{
    fclose(dict);
    return false;
}

额外优化建议

  • 你的哈希函数仅根据首字母分配桶,会导致大量哈希冲突,建议优化哈希逻辑(比如利用整个单词的字符计算哈希值),提升查询效率。
  • 可以在程序启动时显式初始化table数组为NULL(虽然全局数组默认初始化,但显式初始化更清晰):
// 在load函数开头添加
for (int i = 0; i < N; i++)
{
    table[i] = NULL;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:31:58