【问题标题】:freeing memory of a binary tree C释放二叉树的内存 C
【发布时间】:2012-02-29 04:04:12
【问题描述】:

我想从我分配的二叉树中释放内存,这样做的最佳方式是什么?

typedef struct Node{
struct Node * right;
struct Node * left;
void * data;
}Node;


typedef int (*cmp) (void*,void *);


Node* init(void * element){
    Node * newNode=(Node*)malloc(sizeof(Node));
    newNode->data=element;
    newNode->left=NULL;
    newNode->right=NULL;
    return newNode; 
}

void  insert(void * element, Node** root,cmp compareTo){
    if(*root==NULL){
        *root=init(element);
        return;
    }
    if(compareTo(element,(*root)->data)==1)
        insert(element,&((*root)->left),compareTo);
    else
        insert(element,&((*root)->right),compareTo);
}

【问题讨论】:

    标签: c free binary-tree


    【解决方案1】:

    因为它是一棵树,所以你应该使用递归方法。

    deallocate (node):
        //do nothing if passed a non-existent node
        if node is null
            return
    
        //now onto the recursion
        deallocate(left node)
        deallocate(right node)
    
        free node
    

    【讨论】:

    • 如果你的树超级大,递归调用可能会导致堆栈溢出(ahhhhhhh),在这种情况下你会想要走不同的路线(迭代),尽管你会增加时间复杂度.
    【解决方案2】:

    想想不同的遍历类型做了什么,记住,在你释放内存之后,你就不能再访问它了:

    • 预购:在访问任何儿童之前进行的操作
    • 按顺序:访问左子树之后,右子树之前执行的操作
    • 后序:访问所有子树后执行的操作

    鉴于以上陈述,答案应该很清楚了。

    【讨论】:

      【解决方案3】:
      void free_tree(Node * node){
         //post-order like FatalError hinted at
             if (node != NULL) {
              free_tree(node->right);
              free(node->data); //if data was heap allocated, need to free it
              free_tree(node->left);
              free(node);
           }}
      

      检查段错误和内存泄漏的一种很酷的方法是使用

      valgrind --leak-check=full ./yourProgram

      【讨论】:

      • 我认为这没有什么区别,但我希望在释放 node 之前释放 data。不过,我不得不对您的代码三思而后行!
      • 这很好,但我有错误上下文“条件跳转或移动取决于未初始化的值”和“未初始化的值是由堆分配创建的”
      【解决方案4】:

      深度优先搜索最适合这个

      【讨论】:

        【解决方案5】:

        当您说“最佳”时,您的意思是“正确”(即不会通过访问释放的内存而造成混乱)还是“最有效”或什么?

        就正确性而言:任何你喜欢的东西,只要你在释放数据后注意不要访问它。最简单的方法(我不会明确说明,因为这看起来有点像家庭作业:-),但如果你想编写尽可能少的代码,这就是你要做的[编辑添加:这是“cnicutar”发布的内容;我希望这毕竟不是家庭作业!]) 工作得很好。

        通过将释放顺序与分配顺序适当匹配,您可能会获得更有效的结果(在空间或时间上),但细节取决于您的内存分配器,您可能不必在意。

        【讨论】:

          【解决方案6】:
          void deallocate (struct Node * p)
          {
              if(p==NULL)
                  return;
          
              deallocate(p->right);
              deallocate(p->left);
          
              free(p);
          }
          

          在这个函数中传递根,它将释放树使用的所有堆内存

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-12-04
            • 2017-05-11
            • 1970-01-01
            • 2015-12-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-29
            相关资源
            最近更新 更多