我目前正在尝试使用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;
}
}
也许我的代码在返回值和验证方面不是很聪明,但我现在的主要问题是保证递归按预期工作,没有内存泄漏或发生分段错误。有什么建议吗?
提前致谢!
答案 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,如果是,则不执行任何操作。然后,您可以在进行递归调用之前消除检查,现在可以正确防范另一个边缘情况。