在C中释放一棵树

时间:2017-05-21 12:23:37

标签: c malloc free calloc

所以我得到了树的结构,每个节点最多有2个孩子:

typedef struct one_node_t one_node_t;

typedef struct two_nodes_t two_nodes_t;

typedef struct my_tree_t {
  int numberOfNodes; //== 1 || numberOfNodes == 2

   // If the node is a leaf, it is represented by (*oneNode==NULL && numberOfNodes == 1)
    union {
       one_node_t* one;
       two_nodes_t* two;
    } nodeC;
} my_tree_t;

struct one_node_t {
  one_node_t* child;
};

struct two_node_t {
  my_tree_t children[2];
};

现在我正在尝试编写一个函数void freeMyTree(my_tree_t* myTree),它应该释放树myTree指向的分配空间:

void freeMyTree(my_tree_t* myTree) {
  if(myTree->numberOfNodes == 2){
      freeMyTree(myTree->nodeC.two->children);
      freeMyTree(&myTree->nodeC.two->children[1]);
      free(myTree->nodeC.two);
      myTree->nodeC.two = NULL;
  }else{
      if(myTree->nodeC.one->child != NULL)
          freeMyTree(myTree->nodeC.one->child);
      free(myTree->nodeC.one);
      myTree->nodeC.one = NULL;
  }
}

但似乎没有空间被释放。我想我必须对自己如何释放空间有某种误解,但谷歌搜索并没有帮助我理解它。

我认为空间没有被释放,因为我使用带有-fsanitize=leak选项的gcc创建我的文件。

如果我之前创建了my_tree_t* a = calloc(1, sizeof(my_tree_t)) leak sanitizer告诉我,我是否没有释放它。但是在致电freeMyTree(a)之后,它仍会告诉我同样的事情。

修改 错误消息明确表示没有释放一个/两个。因为它们指向的行如下:

my_tree_t t;
t.nodeC.two = calloc(1, sizeof(two_nodes_t)); //<== POINTING TO THIS LINE

2 个答案:

答案 0 :(得分:0)

您所做的free() free(myTree->nodeC.one); free(myTree->nodeC.two);free(myTree->nodeC.one->child);,但我无法看到您执行以下操作:for action in actions: name = action[2] button = QPushButton(name, self.timelineFrame) dir = "actions/{}.mp4".format(name) button.move(...) button.clicked.connect(lambda: self.OpenVid(dir)) button.show()

答案 1 :(得分:0)

这不是一棵树,每个节点最多有2个孩子。这是一棵树,其中每个节点具有正好两个子节点,或者根本没有子节点以及相关联的基本1自然数。事实上,

struct one_node_t {
   one_node_t* child;
};

不包含子树。它是一个链表,节点中没有信息。这种清单所包含的唯一信息就是它的长度。所以这是一些自然数的低效表示。 (我们忽略循环链表的可能性。)

释放此类列表的正确方法是

one = myTree->one;
while (one) {
  tmp = one->child;
  free(one);
  one = tmp;
}