【发布时间】:2016-07-03 22:58:48
【问题描述】:
我想防止内存泄漏,所以我想释放 trie。 您可以在下面看到我尝试释放已使用的内存。
// to see how many words are cleaned up.
static int teller_cleanup = 0;
struct ac {
int value;
char character;
char * word;
struct ac *next;
struct ac *previous;
struct ac *child;
struct ac *parent;
};
它是一个双路或四路链表,不确定我应该调用它。
void cleaner(struct ac* a) {
ac * temp = NULL;
if (a != NULL) {
if (a -> child == NULL && a -> next == NULL) {
teller_cleanup ++;
if (a -> parent != NULL) {
temp = a -> parent;
}
else {
temp = a -> previous;
}
free(a -> word);
free(a);
a = temp;
}
if (a -> child != NULL) {
cleaner(a -> child);
}
if (a -> next != NULL) {
cleaner(a -> next);
}
}
}
int cleanup(struct ac* a) {
// means that it is in the root
// therfore it needs to go to the first node.
if (a -> next == NULL && a -> parent == NULL) {
a = a -> child;
}
cleaner(a);
return teller_cleanup;
}
但它似乎无法正常工作。它给出了一个错误:
双重释放或损坏(fasttop):0x0000000000fffa70 ***
我似乎没有得到什么,因为当'child'和'next'都是'NULL'时,'a'是最外面的节点。而且我相信只有一个递归 if 语句可以到达这些最外面的节点之一。
我将尝试将特里树形象化:
[root]
|
\/
[h] -- > [b]
| |
\/ \/
[i] [y] --> [e]
所以 trie 包含单词 hi、by 和 be。 root 指向第一个单词的第一个字符,所有的箭头都是双链接的。从 'h' 到 'b' 是下一个,从 'h' 到 'i' 是孩子。
有人可以看到我做错了什么吗?将不胜感激。
【问题讨论】:
-
您应该只释放父元素一次,自上而下或自下而上,而不是两种方式 - 如果您使用调试器单步执行您的代码,您会注意到
a = a->parent; [...] if(a->next != NULL) ...之后已删除的子元素 -
请注意,点
.和箭头->运算符绑定得非常紧密,在传统的 C 编码样式中,不应在它们周围有空格。