C语言结构体双指针哈希表的正确内存释放方案排查
修复哈希表内存释放的内存泄漏问题
嘿,我帮你找到了free_table()函数里导致Valgrind报错的两个关键问题:
问题出在哪?
- 漏了释放HASHREC结构体本身:你在遍历链表时只释放了每个节点的
word字符串,但完全忘了释放hashinsert里用malloc分配的HASHREC节点内存——这就是Valgrind提示的“字节丢失”的主要来源。 - 错误调用
free(ht[i]):ht[i]是链表的头指针,当你遍历完整个链表后,所有节点已经被逐个释放了,此时ht[i]要么是初始的NULL,要么是指向已释放内存的野指针,这里调用free完全多余,甚至可能触发未定义行为。
修正后的free_table函数
void free_table(HASHREC **ht) { int i; HASHREC* current; HASHREC* tmp; for (i = 0; i < TSIZE; i++){ current = ht[i]; while(current != NULL) { tmp = current; current = current->next; // 先释放节点的字符串成员(第一层释放) free(tmp->word); // 再释放HASHREC节点本身(第二层释放) free(tmp); } // 这里不需要free(ht[i])!ht[i]只是指针,节点已经被释放了 } // 最后释放哈希表的指针数组(第三层释放) free(ht); }
为什么这样改?
- 我们严格按照你说的三层释放逻辑来:先释放每个节点的
word,再释放节点本身,最后释放整个哈希表的指针数组。 - 移除了错误的
free(ht[i]),因为inithashtable里只是把ht[i]初始化为NULL,并没有为它分配独立的内存(内存都在每个HASHREC节点里),所以不需要单独释放。
这样修改后,Valgrind应该就不会再报告内存泄漏了,所有动态分配的内存都被正确释放了。
内容的提问来源于stack exchange,提问作者flamingo
相关产品推荐
相关产品推荐

