递归释放C中的TRIE结构
我目前正在尝试使用递归释放C中的TRIE结构,c,recursion,trie,C,Recursion,Trie,我目前正在尝试使用递归函数成功释放TRIE结构,但没有成功,但我看到内存丢失 trie结构定义为: typedef struct node { bool is_word; struct node* children[27]; } node; 我全局声明了以下节点*: node* trie = NULL; node* root = NULL; 第二个仅用于跟踪根节点,第一个用于从文件接收单词。到目前为止,在编译程序时,除了内存丢失之外,我没有得到任何错误,而没有释放堆内存 在实
递归函数成功释放TRIE结构
,但没有成功,但我看到内存丢失
trie结构定义为:
typedef struct node
{
bool is_word;
struct node* children[27];
}
node;
我全局声明了以下节点*:
node* trie = NULL;
node* root = NULL;
第二个仅用于跟踪根节点,第一个用于从文件接收单词。到目前为止,在编译程序时,除了内存丢失之外,我没有得到任何错误,而没有释放堆内存
在实现unload()函数之后,我开始遇到分段错误
错误
请参阅我的代码片段:
/*
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;
}
}
/*
递归地逐个释放节点
*/
布尔自由空间(节点*子节点)
{
对于(int i=0;i<27;i++)
{
if(trie->children[i]!=NULL)
{
自由空间(trie->children[i]);
}
}
自由(trie);
返回true;
}
/**
*从内存中卸载字典。如果成功,则返回true;否则返回false。
*/
bool unload()
{
if(root!=NULL)
{
trie=根;
自由空间;
if(自由空间(trie))
返回true;
其他的
返回false;
}
其他的
{
返回false;
}
}
也许我的代码在返回值和验证方面不是很聪明,但我现在的主要问题是确保递归按预期工作,没有内存泄漏或分段错误发生。有什么建议吗
提前谢谢 仔细查看您的代码。您是否在任何地方使用该函数的参数?实际上,每次迭代都会查看全局trie指针,这是您不想做的
要解决此问题,请更改代码,以便查看作为参数传入的节点及其子节点,而不是全局trie指针
还有一个问题需要注意,那就是如何处理空指针。现在,假设参数指针不为null,然后在循环之前检查每个子级以查看它是否为非null。但是如果trie本身一开始是空的呢?我会考虑创建一个基本的案例来检查TIE是否为空,如果是,则不做任何事情。然后,您可以在进行递归调用之前取消检查,现在可以适当地防止另一种边缘情况。仔细查看您的代码。您是否在任何地方使用该函数的参数?实际上,每次迭代都会查看全局trie指针,这是您不想做的
要解决此问题,请更改代码,以便查看作为参数传入的节点及其子节点,而不是全局trie指针
还有一个问题需要注意,那就是如何处理空指针。现在,假设参数指针不为null,然后在循环之前检查每个子级以查看它是否为非null。但是如果trie本身一开始是空的呢?我会考虑创建一个基本的案例来检查TIE是否为空,如果是,则不做任何事情。然后,您可以在进行递归调用之前取消检查,现在可以适当地防止另一种边缘情况。下面是代码片段的修改版本,它更有意义:
/*
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;
}
}
/*
递归地逐个释放节点
*/
无效自由空间(节点*t)
{
对于(int i=0;i<27;i++)
{
如果(t->children[i]!=NULL)
{
自由空间(t->children[i]);
}
}
自由(t);
}
/**
*从内存中卸载字典。如果成功,则返回true;否则返回false。
*/
bool unload()
{
if(root!=NULL)
{
trie=根;
自由空间;
返回true;
}
其他的
{
返回false;
}
}
freeSpace
函数已更改为使用参数作为要释放的trie的基础。您的原始版本有一个未使用的参数child
,并使用了全局变量trie
,这没有意义
freeSpace
不需要返回值,因为它所做的一切都是免费的,它只返回一个固定值true
。我将其返回类型更改为void
您的unload
函数在同一个对象上调用了freeSpace
两次,因此我删除了其中一个调用。以下是您的代码片段的修改版本,更有意义:
/*
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;
}
}
/*
递归地逐个释放节点
*/
无效自由空间(节点*t)
{
对于(int i=0;i<27;i++)
{
如果(t->children[i]!=NULL)
{
自由空间(t->children[i]);
}
}
自由(t);
}
/**
*从内存中卸载字典。如果成功,则返回true;否则返回false。
*/
bool unload()
{
if(root!=NULL)
{
trie=根;
自由空间;
返回true;
}
其他的
{
返回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;
}
bool-freeSpace(节点*子节点){
对于(int i=0;i<27;i++)
{
if(child->children[i]!=NULL)
{
自由空间(child->children[i]);
}
}
免费(儿童);
返回true;
}
我认为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;
}
bool-freeS