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
相关产品推荐
相关产品推荐

