在C语言中删除节点

3

我正在尝试编写一个方法,用于删除一个节点及其所有附加的节点,但是我对该怎么做感到困惑。我知道free方法释放内存,而当我创建节点时,我使用了malloc。我不确定为什么free没有移除节点,应该做些什么。

struct node {
        char *data;
        struct node *left;
        struct node *right;
}*child = NULL;

    void delete(node* root){
        char array[13];
        node *toDelete;
        //takes in name of node to be deleted
        //scan method to find the node to delete and deletes all of the children of the node first before deleting
        printf ("Please specify a name to delete\n");
        scanf("%s", array);
        toDelete = scan(root, array); //return which node to delete
        removeChild(&toDelete);  //helper method here to go through and delete each children
        if(toDelete == NULL) {
                printf("ERROR -- Node does not exist");
        }
}


void removeChild(node **trash){
        if((*trash)->left == NULL && (*trash)->right == NULL) { //no parents
                free(trash);
                *trash = NULL;
        }
        else if((*trash)->left == NULL && (*trash)->right != NULL) { //have mother
                removeChild((*trash)->right);
        }
        else if((*trash)->left != NULL && (*trash)->right == NULL) { //have father
                removeChild((*trash)->left);
        } else{  //have both
                removeChild((*trash)->left);
                removeChild((*trash)->right);
        }
}

你应该检查 scanf 的返回值,并将存储的字符限制为 12,例如 if (scanf ("%12s", array) != 1) { /* 处理错误 */ }。此外,你还应该删除 stdin 中剩余的任何字符(否则它们将被视为下一个输入)。 - David C. Rankin
1个回答

4

我没有仔细查看你的代码,但我看到这个问题,它并不像你想的那样工作:

void removeChild(node * trash){
    if(trash->left == NULL && trash->right == NULL) { //no parents
            free(trash);
            trash = NULL;
    }
 ...

最后一条语句只是清除了参数指针,而调用者的指针(传递给removeChild())并没有被置空。这是因为传递给函数的参数是被复制的,而不是通过引用传递的。
可能会有其他代码依赖于指针被清除,所以这并不能满足要求。

1
换句话说,如果你依赖于在 trash = NULL; 后传递的指针 node * trashNULL,那么只有 removeChild 中的 trash 副本被设置为 NULL,传递给 removeChild 的指针在调用者中不会受到影响。如果你需要这个工作,你需要从调用者传递指针的地址,例如 &nodepointer,并将 removeChild 的参数更改为 node **trash - David C. Rankin
我相应地更改了我的代码,并尝试在适当的位置输入指针,但仍然在removeChild方法上收到一些警告。我有什么没看到的吗? - antelemon
@antelemon:认真对待警告并解决它们。即使在最严格的警告设置下,这段代码也不应该有任何警告。像这样转换指针代码很难做到完美。可能您并不需要将所有指针类型都更改为额外的间接级别,只需要那些需要通过函数(removeChild())进行间接访问的指针类型。 - wallyk
@antelemon:哦,我明白了:你更新了这个函数。在RemoveChild()中,free(trash)应该是free(*trash)。我会留下原因让你自己去思考。 - wallyk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接