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

Speller程序手动测试正常但check50无输出、debug50崩溃求助

Speller项目问题排查与修复

问题现象

  • 代码本地编译运行、手动测试全部通过,但check50测试返回expected "MISSPELLED WOR...", not "",无错误单词输出
  • valgrind检测无内存错误,但debug50中在dictionary.c的任意函数设断点会触发段错误,生成Could not load source ./string/../sysdeps/x86_64/multiarch/strlen-evex.S': 'SourceRequest' not supported..提示
  • 无断点时程序可正常执行

核心问题分析

  1. Hash函数未处理非字母开头的单词:当前hash函数直接取单词首字符计算索引,若单词以非字母(如 apostrophe ')开头,会得到负数索引,触发哈希表数组越界访问的未定义行为。本地字典可能无此类单词,所以手动测试正常,但check50的测试字典包含此类单词,导致哈希表损坏,check函数无法正确识别错误单词。
  2. Check函数遍历所有哈希桶:虽然功能上可行,但效率极低,且在哈希表损坏时容易出现误判。

修复方案

1. 修复Hash函数,处理非字母开头的单词

修改hash函数,跳过单词前的非字母字符,找到第一个有效字母后计算哈希索引,确保返回值在0到N-1范围内:

// Hashes word to a number
unsigned int hash(const char *word)
{
    int i = 0;
    // 跳过非字母字符,找到第一个有效字母
    while (word[i] != '\0' && !isalpha((unsigned char)word[i]))
    {
        i++;
    }
    // 若单词无字母(字典中理论不存在),返回默认桶
    if (word[i] == '\0')
    {
        return 0;
    }
    return tolower((unsigned char)word[i]) - 'a';
}

2. 优化Check函数,仅遍历对应哈希桶

根据单词的哈希值直接定位到对应桶,避免遍历所有桶,提升效率并减少误判:

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    unsigned int bucket = hash(word);
    node *trav = table[bucket];
    while (trav != NULL)
    {
        if (strcasecmp(trav->word, word) == 0)
        {
            return true;
        }
        trav = trav->next;
    }
    return false;
}

3. debug50段错误说明

该错误是gdb尝试读取系统库函数strlen的汇编源文件但找不到导致的,属于环境问题,与代码逻辑无关。修复代码后,功能正常时可忽略此提示,或在调试时跳过系统库函数的断点。

验证步骤

  1. 重新编译代码:执行make clean && make
  2. 本地测试:使用包含非字母开头单词的字典测试,确保功能正常
  3. 运行check50:验证测试用例是否通过
  4. debug50调试:虽然仍可能出现strlen源文件提示,但代码逻辑可正常断点调试

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 05:45:38