CS50x2022习题集5 Speller check函数匹配少量错拼词后停止运行问题
问题根因
程序运行几个单词就卡死、Debug50报"Unknown stopping event"的核心bug在check函数,你怀疑的load函数存在不规范问题,但不是触发本次卡死的直接原因。
check函数的致命错误
多余的内存分配造成内存泄漏
你给遍历用的cursor指针单独malloc了一块新的节点内存,这块内存不存储任何有效词典数据,遍历开始后cursor就顺着链表移动到词典节点上,最初分配的这块内存再也找不到引用,每调用一次check就泄漏一块内存。误释放哈希表节点破坏链表结构
遍历退出时cursor已经指向哈希表中存储的真实单词节点(不是你最初malloc的临时节点),此时调用free(cursor)会直接把词典链表的节点释放掉,导致链表出现野指针。后续遍历访问到这块被回收的内存时,就会触发内存访问错误、死循环,直接导致程序无响应。遍历逻辑冗余
你初始将cursor->next指向链表表头,遍历全程操作cursor->next的内容,多套了一层无意义的指针跳转。
修正后的check实现
bool check(const char *word) { int hash_word = hash(word); // 游标直接指向桶的第一个数据节点,不需要额外分配内存 node *cursor = table[hash_word]->next; while (cursor != NULL) { if (strcasecmp(word, cursor->word) == 0) { return true; } cursor = cursor->next; } // check阶段只做读操作,不释放任何词典节点,节点内存留到unload阶段统一回收 return false; }
load函数的待修复问题(不触发本次卡死,但不符合作业要求)
- 返回值逻辑写反:打开文件失败、节点内存分配失败时属于加载失败,应该返回
false(也就是0),你现在返回1对应true,会让程序误以为加载成功。 - 硬编码单词数:写死循环次数143091只适配默认的大词典,换其他词典会出现读取不全、越界读取文件的问题,应该改为循环读取文件直到
fscanf返回EOF再停止。 - 计数逻辑错误:你在读单词之前就给单词计数加1,如果后续fscanf读取失败,计数会比实际加载的单词数多1。
内容的提问来源于stack exchange,提问作者Marcis
相关产品推荐
相关产品推荐

