递归释放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