如何释放树占用的内存,C?

时间:2015-05-17 18:59:16

标签: c tree free

我目前正在处理具有这种结构的通用树:

ALTER TABLE table_name RENAME old_col_name TO new_col_name;

虽然分配不同节点的功能是(不要过多地关注键的值,基本上分配子节点。如果没有任何新子进入左子节点,否则它会进入列表的末尾“node-> leftchild-> rightbrothers”):

typedef struct NODE {

    //node's keys
    unsigned short *transboard;
    int depth;
    unsigned int i; 
    unsigned int j;
    int player;
    int value;


    struct NODE *leftchild; //points to the first child from the left
    struct NODE *rightbrothers; //linked list of brothers from the current node

}NODE;

static NODE *GameTree = NULL;

我需要提出一个函数,可能是递归的,解除整个树的释放,到目前为止我已经想出了这个:

static int AllocateChildren(NODE **T, int depth, unsigned int i, unsigned int j, int player, unsigned short *transboard) {
NODE *tmp = NULL;

if ((*T)->leftchild == NULL) {
    if(  (tmp = (NODE*)malloc(sizeof(NODE))  )== NULL) return 0;
    else {
        tmp->i = i;
        tmp->j = j;
        tmp->depth = depth;
        (player == MAX ) ? (tmp->value = 2 ): (tmp->value = -2);
        tmp->player = player;
        tmp->transboard = transboard;

        tmp->leftchild = NULL;
        tmp->rightbrothers = NULL;

        (*T)->leftchild = tmp;
    }
}

else {
    NODE *scorri = (*T)->leftchild;
    while (scorri->rightbrothers != NULL)
        scorri = scorri->rightbrothers;

    if( ( tmp = (NODE*)malloc(sizeof(NODE)) )== NULL) return 0;
    else {
        tmp->i = i;
        tmp->j = j;
        tmp->depth = depth;
        (player == MAX) ? (tmp->value = 2) : (tmp->value = -2);
        tmp->player = player;
        tmp->transboard = transboard;

        tmp->leftchild = NULL;
        tmp->rightbrothers = NULL;
    }
    scorri->rightbrothers = tmp;


}

return 1;

}

但它似乎没有用,它甚至没有释放单个内存节点。 我对错误或如何实施的想法? 附:我从老师的伪代码中得到了递归函数的想法。但是我不确定我是否已经使用我的树种在C中正确翻译了它。 伪代码:

 void DeleteTree(NODE **T) {

 if((*T) != NULL) {
    NODE *tmp;
    for(tmp = (*T)->children; tmp->brother != NULL; tmp = tmp->brother) {
        DeleteTree(&tmp);
    }

    free(*T);

 }
}

3 个答案:

答案 0 :(得分:0)

如果我要分配大量的树节点(我将同时消失),我喜欢做的一件事就是在'批次'中分配它们。然后我malloc作为一个节点数组,在保存指向数组的指针后(在下面的函数中)从特殊的nodealloc函数中删除它们。要删除树,我只是确保我没有保留任何引用,然后调用自由例程(也如下所示)。

如果您对初始malloc幸运(或非常聪明)或者可以信任realloc在缩小块时不移动块,这也可以减少您分配的RAM量。

struct freecell { struct freecell * next; void * memp; } * saved_pointers = 0;

static void
save_ptr_for_free(void * memp)
{
    struct freecell * n = malloc(sizeof*n);
    if (!n) {perror("malloc"); return; }
    n->next = saved_pointers;
    n->memp = memp;
    saved_pointers = n;
}

static void
free_saved_memory(void)
{
    while(saved_pointers) {
        struct freecell * n = saved_pointers;
        saved_pointers = saved_pointers->next;
        free(n->memp);
        free(n);
    }
}

答案 1 :(得分:0)

我刚刚在代码中意识到我的大错,因为没有人找到答案,我只会自己回答。

错误在于这段代码:

for(tmp = (*T)->children; tmp->brother != NULL; tmp = tmp->brother) {
    DeleteTree(&tmp);
}

首先Ami Tavory对于for条件是正确的,我需要继续只要tmp!= NULL 基本上它不会起作用,因为在DeleteTree(& tmp)之后,我无法再访问tmp中的内存因为它显然被删除,所以在第一个循环结束后我不能do tmp = tmp-> rightbrother移动下一个要删除的节点因为tmp-> rightbrother不再存在,因为我刚删除它。 为了解决这个问题,我只需要在其他地方保存tmp->兄弟:

void DeleteTree(NODE **T) {

   if((*T) != NULL) {
       NODE *tmp, *deletenode, *nextbrother;

       for(tmp = (*T)->children; tmp != NULL; tmp = nextbrother) {
           nextbrother = tmp->rightbrother;
           DeleteTree(&tmp);

       }

   canc = (*T);
   free(*T);
   (*T) = NULL;
  }

}

答案 2 :(得分:0)

为了完整起见,我想添加我的DeleteTree版本

void DeleteTree(NODE *T) {
  if(T != NULL) {
    DeleteTree(T->rightbrothers);
    DeleteTree(T->leftchild);
    free(T);
  }
}

我认为它不那么模糊,也​​更容易阅读。基本上它解决了DeleteTree中的问题,但通过消除循环。

由于我们递归地释放节点,我们也可以递归地执行整个过程。