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

Valgrind提示blocks are still reachable内存泄漏该如何解决?

内存泄漏原因

核心问题出在自定义的链表释放函数free_list逻辑存在错误,仅释放了链表的尾节点,其余所有节点都没有被正确释放:
你当前的free_list执行逻辑如下:

  1. 若传入节点为空,直接返回
  2. 若传入节点是尾节点(next为NULL),释放该节点后返回
  3. 若传入节点不是尾节点,仅递归处理下一级节点,完全没有释放当前节点
    这就导致除了每个哈希桶的链表尾节点外,其余所有你在load函数里通过malloc申请的节点都没有被释放,Valgrind检测到这些节点还被全局哈希表table的指针指向,所以归类为still reachable类型的内存泄漏。
修复方案

直接修正free_list的释放逻辑即可,遵循「先释放后继链表,再释放当前节点」的递归释放规则,修改后代码如下:

bool free_list(node *w)
{
    if (w == NULL)
    {
        return true;
    }
    // 先递归释放当前节点的后续所有节点
    free_list(w->next);
    // 再释放当前节点本身
    free(w);
    return true;
}

如果担心链表过长导致递归栈溢出,也可以换成迭代版本的实现,性能和稳定性更好:

bool free_list(node *w)
{
    node *curr = w;
    while (curr != NULL)
    {
        node *next_node = curr->next;
        free(curr);
        curr = next_node;
    }
    return true;
}

可选优化

你当前的load函数仅在读取到换行符时才会将暂存的单词插入哈希表,如果加载的字典文件最后一个单词末尾没有换行符,会导致最后一个单词丢失,你可以在load函数的fclose(dict)之前补充如下逻辑处理该情况:

// 处理字典末尾无换行的最后一个单词
if (index > 0)
{
    tmp[index] = '\0';
    node *n = malloc(sizeof(node));
    if (n == NULL)
    {
        unload();
        fclose(dict);
        return false;
    }
    n->next = table[hash(tmp)];
    strcpy(n->word, tmp);
    table[hash(tmp)] = n;
    word_count += 1;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:06:00