C 释放堆上的内存,特殊树

C 释放堆上的内存,特殊树,c,memory,tree,heap,free,C,Memory,Tree,Heap,Free,我有一个树形结构 节点{节点*左,节点*右}。 我是这样填的: 假设A是根。 A1和A2是孩子们。 然后是A11和A12,它们是A11的孩子。 最后,A12(=A21)和A22是A22的孩子。 A11和A12有一个共同的孩子,我没有复制这个孩子,我们只有A12=A21(在地址方面)。 但是,要释放该树,唯一的方法是使用recursif函数: 要释放树T(由指针节点*表示),请释放两个子级(如果存在)(即不为NULL),然后使用free(T)。 问题是,当recursif调用在A21上时,指针将被

我有一个树形结构 节点{节点*左,节点*右}。 我是这样填的: 假设A是根。 A1和A2是孩子们。 然后是A11和A12,它们是A11的孩子。 最后,A12(=A21)和A22是A22的孩子。 A11和A12有一个共同的孩子,我没有复制这个孩子,我们只有A12=A21(在地址方面)。 但是,要释放该树,唯一的方法是使用recursif函数: 要释放树T(由指针节点*表示),请释放两个子级(如果存在)(即不为NULL),然后使用free(T)。 问题是,当recursif调用在A21上时,指针将被释放(因为A21=A12,并且之前对A12进行了recursif调用),这导致了问题。 我怎样才能修好它? 谢谢

编辑。 我试图通过在结构中添加一个代表正确兄弟的新字段来修复它, 这可能是因为valgrind没有注意到任何内存的丢失:D

#include <stdio.h>
#include <stdlib.h>
struct node{
    struct node *lc, *rc, *bro; // left child, right child, brother
};
typedef struct node node;

void release(node *n)
{
    if(n->lc)
        release(n->lc);
    if(n->rc){
        if(n->bro) // in that case, n and n->bro have a common node
            n->bro->lc = NULL; // so i set it to NULL because it must be released only once
        release(n->rc);
    }
    free(n);
}

int main()
{
    node *A22 = malloc(sizeof *A22);
    A22->lc = A22->rc = A22->bro = NULL;

    node *A21 = malloc(sizeof *A21);
    A21->lc = A21->rc = NULL;
    A21->bro = A22;

    node *A2 = malloc(sizeof *A2);
    A2->lc = A21;
    A2->rc = A22;
    A2->bro = NULL;

    node *A11 = malloc(sizeof *A11);
    A11->lc = A11->rc = NULL;
    A11->bro = A11;

    node *A12 = A21; // the duplicated node

    node *A1 = malloc(sizeof *A1);
    A1->lc = A11;
    A1->rc = A12;
    A1->bro = A2;

    node *A = malloc(sizeof *A); // root
    A->lc = A1;
    A->rc = A2;
    A->bro = NULL;

    release(A);
    return 0;
}
#包括
#包括
结构节点{
结构节点*lc,*rc,*bro;//左子节点,右子节点,兄弟节点
};
typedef结构节点;
无效释放(节点*n)
{
如果(n->lc)
释放(n->lc);
如果(n->rc){
如果(n->bro)//在这种情况下,n和n->bro有一个公共节点
n->bro->lc=NULL;//所以我将它设置为NULL,因为它只能被释放一次
释放(n->rc);
}
自由(n);
}
int main()
{
节点*A22=malloc(sizeof*A22);
A22->lc=A22->rc=A22->bro=NULL;
节点*A21=malloc(sizeof*A21);
A21->lc=A21->rc=NULL;
A21->bro=A22;
节点*A2=malloc(sizeof*A2);
A2->lc=A21;
A2->rc=A22;
A2->bro=NULL;
节点*A11=malloc(sizeof*A11);
A11->lc=A11->rc=NULL;
A11->bro=A11;
node*A12=A21;//复制的节点
节点*A1=malloc(sizeof*A1);
A1->lc=A11;
A1->rc=A12;
A1->bro=A2;
node*A=malloc(sizeof*A);//根
A->lc=A1;
A->rc=A2;
A->bro=NULL;
释放(A);
返回0;
}

这很粗糙,但您可以维护一个已释放节点的全局列表(按每个节点的地址),以便您可以引用它并避免重新释放任何节点。

任何代码/代码片段?不清楚您如何决定何时“重新使用”子节点。