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

CS50 Pset5 Speller程序内存错误求助:非法访问8字节内存

CS50 Pset5 Speller 内存错误修复

问题概况

完成CS50问题集5的Speller程序后,所有功能正常运行,但Valgrind检测出内存错误:unload函数中ptr = tmp->next(dictionary.c第104行)存在非法内存访问,错误总数143091个,虽无内存泄漏但存在大量无效内存读取。

错误原因

当前unload函数的内存释放逻辑存在顺序错误:

while (ptr != NULL)
{
    tmp = ptr;
    free(ptr);
    ptr = tmp->next;
}

tmp与ptr指向同一块内存,调用free(ptr)后该内存已被操作系统回收,此时再通过tmp->next访问已释放的内存,属于无效内存读取,触发Valgrind错误提示。

修复方案

调整内存释放顺序,先保存下一个节点的地址,再释放当前节点:

// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
    node *current = NULL, *next_node = NULL;
    for (int i = 0; i < N; i++)
    {
        current = table[i];
        while (current != NULL)
        {
            // 先保存下一个节点的地址,避免释放后丢失
            next_node = current->next;
            // 释放当前节点
            free(current);
            // 移动到预先保存的下一个节点
            current = next_node;
        }
        // 将桶指针置空,避免悬空指针
        table[i] = NULL;
    }
    return true;
}

修改说明

  1. 提前用next_node保存下一个节点的地址,确保当前节点释放后仍能正常遍历链表。
  2. 释放当前节点后,直接使用预存的next_node更新循环变量,彻底避免访问已释放内存。
  3. 添加table[i] = NULL,将每个哈希桶的指针置空,防止后续误操作访问悬空指针。

验证

修改后重新用Valgrind检测,ERROR SUMMARY会显示为0个错误,内存释放逻辑完全合法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:39:58