以递归方式释放C中的TRIE结构

时间:2017-08-09 16:18:09

标签: c recursion trie

我目前正在尝试使用TRIE structure成功释放recursive function但无济于事,但我看到了内存丢失。

trie结构定义为:

typedef struct node
{
    bool is_word;
    struct node* children[27];
}
node;

我在全球范围内声明了以下Node *:

node* trie = NULL;
node* root = NULL;

第二个用于跟踪根节点,第一个用于接收文件中的单词。到目前为止,在没有释放堆内存的情况下编译程序时我没有遇到任何错误,除了内存丢失。

实现unload()函数后,我开始遇到Segmentation Fault错误。

查看我的代码片段:

/*
Frees node by node recursively
*/

bool freeSpace(node* child)
{   
    for (int i = 0; i < 27; i++)
    {
        if(trie->children[i] != NULL)
        {
            freeSpace(trie->children[i]);
        }
    }
    free(trie);
    return true;
}

/**
 * Unloads dictionary from memory. Returns true if successful else false.
 */ 
bool unload()
{

    if(root != NULL)
    {
        trie = root;
        freeSpace(trie);

        if(freeSpace(trie))
            return true;
        else
            return false;
    }
    else
    {
        return false;
    }

}

也许我的代码在返回值和验证方面不是很聪明,但我现在的主要问题是保证递归按预期工作,没有内存泄漏或发生分段错误。有什么建议吗?

提前致谢!

3 个答案:

答案 0 :(得分:4)

以下是您的代码段的修改版本,它更有意义:

freeSpace

child函数已更改为使用参数作为要释放的trie的基础。您的原始版本有一个未使用的参数trie,而是使用全局变量freeSpace代替,这没有用。

true不需要返回一个值,因为它所做的只是免费的东西,它只返回一个固定值void。我将其返回类型更改为unload

您的freeSpace函数在同一个对象上调用<style> .infomsg {display:none;} </style> 两次,因此我删除了其中一个调用。

答案 1 :(得分:2)

我认为你的freeSpace()函数应该使用子参数而不是trie。这就是它的样子。

bool freeSpace(node* child){   
    for (int i = 0; i < 27; i++)
    {
        if(child->children[i] != NULL)
        {
            freeSpace(child->children[i]);
        }
    }
    free(child);
    return true;
}

答案 2 :(得分:1)

仔细查看您的代码。你真的在任何地方使用参数吗?你实际上总是在每次迭代时查看全局trie指针,这是你不希望的。

要解决此问题,请更改代码,以便查看作为参数传递的节点及其子节点而不是全局特里指针。

你需要注意另一个问题,那就是你如何处理空指针。现在,您假设参数指针不为null,然后检查每个子项以在重复之前查看它是否为非null。但是如果trie本身开头是空的呢?我会考虑创建一个基本案例,检查trie是否为null,如果是,则不执行任何操作。然后,您可以在进行递归调用之前消除检查,现在可以正确防范另一个边缘情况。