简体   繁体   English

C二进制搜索树插入指针问题

[英]C Binary Search Tree Insertion Pointer Issue

I am trying to implement binary search tree insertion but running into problems. 我正在尝试实现二进制搜索树插入,但是遇到了问题。

I have implemented the tree using the following Node and Tree structs 我已经使用以下Node和Tree结构实现了树

typedef struct Node {
    double value;

    struct Node *parent;
    struct Node *right_child;
    struct Node *left_child;
} Node;

typedef struct Tree {
    struct Node *root;
} Tree;

The following is the insert function 以下是插入功能

void insert(Tree *t, Node n) {

    Node *x = t->root, *y = NULL;

    //follow tree down until we reach a leaf of the tree
    while (x != NULL) {

        //save last non-NULL value. We will insert node n as a child to this leaf.
        y = x;

        if (n.value < x->value) {
            x = x->left_child;
        } else {
            x = x->right_child;
        }

    }

    //The parent of the node to insert is the leaf we reached
    n.parent = y;

    //If n is greater than y then it is its right child and vice-versa.
    if (n.value > y->value) {
        y->right_child = &n;
    } else {
        y->left_child = &n;
    }

}

When I run this in my main method 当我在主要方法中运行此命令时

int main(void) {

    Node n1;
    Node n2;
    Node n3;


    n1.value = 4;
    n1.parent = NULL;
    n1.left_child = NULL;
    n1.right_child = NULL;

    n2.value = 2;
    n2.parent = NULL;
    n2.left_child = NULL;
    n2.right_child = NULL;

    n3.value = 1;
    n3.parent = NULL;
    n3.left_child = NULL;
    n3.right_child = NULL;

    Tree t;

    t.root = &n1;

    insert(&t,n2);

    insert(&t,n3);

    printf("n1 left child %f \n", n1.left_child->value);

    return EXIT_SUCCESS;
}

It prints n1 left child 1.000000 which is incorrect. 它打印n1 left child 1.000000 ,这是不正确的。 It should be 2. I have tried inserting print statements for debugging and it appears that the insert function is assigning children at the end to the wrong pointer (ie the n2 node is not persisting after it is inserted). 应该是2。我尝试插入打印语句进行调试,并且似乎insert函数在最后将子代分配给错误的指针(即, n2节点在插入后不再持久)。 So I think this means there is something wrong with y . 所以我认为这意味着y I don't think y is representing what I want it to which is a pointer to the leaf node in the tree (where I will insert the new node n). 我不认为y表示我想要的是指向树中叶子节点的指针(我将在其中插入新节点n)。

You are taking the address of a temporary variable, and you dereference it after it's deallocated and that means your program invokes undefined behavior . 您正在使用一个临时变量的地址,并在释放该变量后对其取消引用,这意味着您的程序将调用未定义的行为 In

void insert(Tree *t, Node n)

The Node n parameter is allocated within the stack frame of the insert() function, when the function returns the frame is destroyed leading to n being deallocated. Node n参数分配在insert()函数的堆栈框架中,当该函数返回时,该框架将被破坏,导致n被释放。

You hold a pointer to it's address in Tree *t; 您在Tree *t;持有指向其地址的指针Tree *t; , accessing that pointer is invalid after the function has returned. ,函数返回后访问该指针无效。

You must pass a pointer to the address of n2 and n3 from main() , like this 您必须从main()传递一个指向n2n3地址的指针,像这样

insert(&t, &n2);
insert(&t, &n3);

and change insert() to directly accept the pointer instead of a local copy of the instance. 并更改insert()以直接接受指针,而不是实例的本地副本。

With my suggested solution n2 and n3 are allocated within the stack frame of main() and thus have a lifetime equal to the whole program lifetime, since you would be passing their address the pointers to the nodes in your tree would still point to valid memory after insert() has returned and you will be able to print their contents without invoking undefined behavior. 使用我建议的解决方案, n2n3分配在main()的堆栈帧内,因此其生命周期等于整个程序的生命周期,因为您将传递它们的地址,指向树中节点的指针仍将指向有效内存在insert()返回之后,您将能够打印其内容而无需调用未定义的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM