清理双链表 c中的Trie结构

  • 本文关键字:中的 Trie 结构 链表 c trie
  • 更新时间 :
  • 英文 :


我想防止内存泄漏,所以我想释放trye。下面您可以看到我尝试释放已使用的内存。

// 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;
};

这是一个双向或 4 路链表,不确定我应该计算什么。

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;
}

但它似乎无法正常工作。 它给出了一个错误:

双重释放或损坏(快速顶部):0x0000000000fffa70***

我似乎没有得到什么,因为当"孩子"和"下一个"都是"NULL"时,"a"是最外层的节点。而且我相信只有一个回避 if 语句可以转到其中大多数节点之一。

我将尝试可视化 trie:

[root]
   |
  /
[h] -- > [b]
 |        |
/       /
[i]      [y] --> [e] 

所以 trie 包含单词 hi, by 和 be。 根指向第一个单词的第一个字符,所有箭头都是双重链接的。 从"H"到"B"是下一个,从"H"到"I"是孩子。

有人能看出我做错了什么吗?将不胜感激。

我认为您在多个地方检查NULL使其变得太复杂了。当您有多个递归时,在输入函数后检查NULL比在调用函数之前更容易

此外,如果通过指向 cleaner() 的指针传递局部变量,则可以避免全局teller_cleanup变量。

void cleaner(struct ac *a, int *teller_cleanup) 
{
    if (a != NULL) {
        cleaner(a->next, teller_cleanup);
        cleaner(a->child, teller_cleanup);
        free(a->word);
        free(a);
        (*teller_cleanup)++;
    }
}
int cleanup(struct ac *a)
{
    int teller_cleanup = 0;
    cleaner(a, &teller_cleanup);
    return teller_cleanup;
}

最新更新