递归释放 C 中的 TRIE 结构



我目前正在尝试使用recursive function成功释放TRIE structure,但无济于事,但我看到记忆丧失。

trie 结构定义为:

typedef struct node
{
bool is_word;
struct node* children[27];
}
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;
}
}

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

提前感谢!

下面是代码片段的修改版本,更有意义:

/*
Frees node by node recursively
*/
void freeSpace(node* t)
{   
for (int i = 0; i < 27; i++)
{
if(t->children[i] != NULL)
{
freeSpace(t->children[i]);
}
}
free(t);
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/ 
bool unload()
{
if(root != NULL)
{
trie = root;
freeSpace(trie);
return true;
}
else
{
return false;
}
}

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

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

您的unload函数在同一对象上调用freeSpace两次,因此我删除了其中一个调用。

我认为你的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;
}

仔细查看您的代码。您实际上是否在任何地方使用该参数?实际上,您总是在每次迭代时查看全局trie指针,这不是您想要做的。

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

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

最新更新