释放指向struct的双指针的正确方法

释放指向struct的双指针的正确方法,c,pointers,gcc,memory-leaks,valgrind,C,Pointers,Gcc,Memory Leaks,Valgrind,我试图将内存释放添加到旧的C代码中。 我有一个自定义对象的哈希表(HASHREC)。在分析了当前代码并阅读了其他SO问题之后,我知道我需要提供三个级别的释放。第一个单词成员,下一个HASHREC*,然后是HASHREC** 我版本的free_table()函数释放提到的对象。不幸的是,Valgrind仍然抱怨某些字节丢失 我无法提供完整的代码,它将太长,但我将介绍如何在inithashtable()和hashinsert()中填充HASHREC**vocab_散列。 你能给我一个建议我该如何修理

我试图将内存释放添加到旧的C代码中。 我有一个自定义对象的哈希表(HASHREC)。在分析了当前代码并阅读了其他SO问题之后,我知道我需要提供三个级别的释放。第一个单词成员,下一个HASHREC*,然后是HASHREC**

我版本的free_table()函数释放提到的对象。不幸的是,Valgrind仍然抱怨某些字节丢失

我无法提供完整的代码,它将太长,但我将介绍如何在inithashtable()和hashinsert()中填充HASHREC**vocab_散列。 你能给我一个建议我该如何修理免费的桌子吗

typedef结构hashrec{
字符*字;
长计数;
结构hashrec*next;
}哈什雷克;
HASHREC**inithashtable(){
int i;
HASHREC**ht;
ht=(HASHREC**)malloc(sizeof(HASHREC*)*TSIZE);
对于(i=0;iword,w)!=0;hprv=htmp,htmp=htmp->next);
if(htmp==NULL){
htmp=(HASHREC*)malloc(sizeof(HASHREC));//word=(char*)malloc(strlen(w)+1;
strcpy(htmp->word,w);
htmp->next=NULL;
如果(hprv==NULL)ht[hval]=htmp;
else hprv->next=htmp;
}
否则{/*新记录不会移到前面*/
htmp->count++;
如果(hprv!=NULL){/*在访问时移动到前面*/
hprv->next=htmp->next;
htmp->next=ht[hval];
ht[hval]=htmp;
}
}
回来
}
无空表格(哈希表**ht){
int i;
HASHREC*电流;
HASHREC*tmp;
对于(i=0;i下一步;
免费(tmp->word);
}
自由(ht[i]);
}
自由(ht);
}
int main(int argc,字符**argv){
HASHREC**vocab_hash=inithashtable();
// ...
hashinsert(vocab_hash,w);
//....
free_表(vocab_散列);
返回0;
}

我认为问题出在这里:

current = ht[i];
while(current != NULL) {
    tmp = current;
    current = current->next;
    free(tmp->word);
}
free(ht[i]);
您可以释放
word
,但不释放
tmp
。释放链表中的第一项后,而不是释放导致泄漏的其他项

在那里释放
tmp
,之后不要释放
ht[i]
,因为它已经在这里释放了

current = ht[i];
while(current != NULL) {
    tmp = current;
    current = current->next;
    free(tmp->word);
    free(tmp);
}

“不幸的是,Valgrind仍然抱怨一些字节丢失了”-Valgrind具体抱怨什么(它声称的分配被泄露的实际代码)应该是您发布的问题的一部分。假设您使用调试符号进行构建,valgrind应该准确地宣布上面代码中哪些
malloc
调用出现泄漏,这就是您应该关注的地方。顺便说一句,我相信萨米在发布的答案中是正确的。@WhozCraig,谢谢你的评论,我在Valgrind指出的上面一行标记为“你在这里复制了相当多的内容。看起来你只需要
TSIZE
HASHFN
SEED
scmp
,和
w
current = ht[i];
while(current != NULL) {
    tmp = current;
    current = current->next;
    free(tmp->word);
    free(tmp);
}