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

Pset5内存泄漏排查求助:定位代码中的内存泄漏点

分析你的内存泄漏问题及修复方案

我帮你梳理了代码里的几处内存泄漏和逻辑错误,下面逐一拆解说明:

1. load函数中无意义的malloc导致泄漏

在load函数里,这段代码完全多余且直接造成内存泄漏:

node *h = malloc(sizeof(node));
if (h == NULL)
    table[pos] = n;
else {
    n->next = table[pos];
    table[pos] = n;
}

你malloc了h但从未使用或释放它——不管h是否为空,后续逻辑都没用到这个指针,相当于每次循环都丢了一块node大小的内存。

修复方案:删掉这段冗余代码,直接用头插法把节点加入哈希表即可:

int pos = hash(n->word);
// 头插法插入新节点
n->next = table[pos];
table[pos] = n;

2. check函数中错误的malloc与free

在check函数里,你先执行了node *ptr = malloc(sizeof(node));,紧接着又把ptr赋值为table[h]——这就导致刚malloc的内存指针直接丢失,永远无法释放,形成泄漏。此外,你在找到匹配单词时执行free(ptr),这会错误释放字典里的节点,后续unload时会出现重复释放或访问已释放内存的问题。

修复方案:不需要malloc指针,直接用栈上指针指向哈希表的链表头部即可:

bool check(const char *word) {
    int h = hash(word);
    node *ptr = table[h]; // 直接指向链表头,无需malloc
    while (ptr != NULL) {
        if (strcasecmp(ptr->word, word) == 0) {
            return true;
        }
        ptr = ptr->next;
    }
    return false;
}

3. unload函数中多余的malloc和逻辑错误

Valgrind提示的第109行(node *ptr = malloc(sizeof(node));)就在这里:你malloc了ptr和tmp,但同样没有使用它们的malloc内存,直接把ptr赋值为table[i],导致这两块内存泄漏。同时你的循环逻辑也有问题,初始tmp是malloc的非空值,进入循环后会触发错误操作。

修复方案:不需要malloc指针,直接用临时指针遍历并释放链表节点:

bool unload(void) {
    for (int i = 0; i < N; i++) {
        node *ptr = table[i];
        // 遍历释放链表的每个节点
        while (ptr != NULL) {
            node *tmp = ptr;
            ptr = ptr->next;
            free(tmp);
        }
    }
    return true; // 原代码返回false是逻辑错误,释放成功应返回true
}

额外的小优化点

  • 全局变量counter需要初始化为0,否则可能会出现不确定的字典计数。
  • 当前hash函数的乘积逻辑容易触发整数溢出,可以考虑更稳定的哈希实现(比如累加字符值取模),不过这和内存泄漏无关。

把这些问题修复后,再用Valgrind检测,应该就能解决所有内存泄漏问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:47:49