【问题标题】:Freeing linked structs in C在 C 中释放链接结构
【发布时间】:2011-07-25 14:01:08
【问题描述】:

好的,所以我有一个仅使用 C 结构和指针构建的二叉搜索树,因为我疯了,不想使用 C++。无论如何,我有一些严重的内存泄漏,因为我假设 free(tree),树是下面结构的一个实例,并没有释放所有的孩子那棵树。

这是我的节点:

struct node{
    struct node* parent;
    struct node* left;
    struct node* right;
    int key; //the value of the node
};

这是我的bst:

struct bst{
    struct node* root;
    int elements; //number of nodes in the bst
};

所以我的问题是,有没有比递归调用删除函数更好的方法呢?例如(当场写这个):

void delete_tree(struct node* n){
    if(n == NULL) return;
    struct node* left = n->left;
    struct node* right = n->right;
    free(n);
    delete_tree(left);
    delete_tree(right);
}

【问题讨论】:

    标签: c data-structures memory-management struct free


    【解决方案1】:

    我认为递归删除绝对没有问题。您可以使用迭代方法,但它没有任何明显的好处并且更难编写。

    顺便说一下,你可以稍微简化一下代码,去掉两个局部变量:

    void delete_tree(struct node* n){
        if(n == NULL) return;
        delete_tree(n->left);
        delete_tree(n->right);
        free(n);
    }
    

    【讨论】:

    • 我敢肯定还有其他方法,我只是看不出有什么特别的理由让它们变得更好。这真的很容易正确编写,这对我来说是一个很大的优点。
    • @Greg:嗯,您也可以使用迭代方法,但无论如何,您必须触摸每个节点一次才能找到并删除子节点,然后正如大卫所说,递归解决方案是可读且易于验证/维护的。
    • @Greg Flynn- 不,C 没有任何类型的递归“自毁”能力。你必须自己写。您的代码按原样相当接近,只需在对 delete_tree 的两次递归调用之后添加一行释放 n 即可。
    • @Greg 顺便说一句,如果你在递归调用 delete_tree 之后编写 free ,那么你就不需要那些讨厌的本地人 - 请参阅我的更新
    • 这里要警惕递归删除的一个原因是,如果树不平衡 - 那么您可能会使用大量堆栈。但是不平衡的树并不擅长 BST 的“搜索”部分,所以在这种情况下你可能担心的不仅仅是这件事。
    【解决方案2】:

    您正在进行递归调用,但从未真正调用free。您可能需要验证一个节点是否为叶节点(可能询问两个子节点是否为空)并在该节点上调用free

    【讨论】:

    • if(n == NULL) return; 检查叶子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    相关资源
    最近更新 更多