简体   繁体   English

C段错误中的二叉搜索树

[英]Binary Search Tree in C Segmentation Fault

I've been trying to implement a simple binary search tree in C just as an exercise.我一直在尝试用 C 实现一个简单的二叉搜索树作为练习。 I can insert elements into the tree, but at certain points (I haven't been able to figure out where) I'm getting a segmentation fault.我可以将元素插入树中,但在某些点(我无法弄清楚在哪里)我遇到了分段错误。

Here is my code:这是我的代码:

#include <stdio.h>
#include <stdlib.h>

struct node {
    struct node *left;
    struct node *right;
    int key;
};

void insert(struct node *treeNode, int key);
void outputTree(struct node *root);

int main(){
    //Store how many numbers the user will enter
    printf("How many numbers will you enter? > ");
    int numNumbers;
    scanf("%d", &numNumbers);

    //Create a root node
    struct node root;
    root.key = -1; //-1 Means the root node has not yet been set
    root.right = NULL;
    root.left = NULL;

    //Now iterate numNumbers times
    int i;
    for(i = 1; i <= numNumbers; ++i){
        int input;
        scanf("%d", &input);
        insert(&root, input);
    }

    outputTree(&root);

    return 0;
}

void insert(struct node *treeNode, int key){
    //First check if the node is the root node
    if((*treeNode).key == -1){
        printf("Root node is not set\n");
        (*treeNode).key = key; //If the root node hasn't been initialised
    }
    else {
        //Create a child node containing the key
        struct node childNode;
        childNode.key = key;
        childNode.left = NULL;
        childNode.right = NULL;

        //If less than, go to the left, otherwise go right
        if(key < (*treeNode).key){
            if((*treeNode).left != NULL){ 
                printf("Left node is not null, traversing\n");
                insert((*treeNode).left, key);
            }
            else {
                printf("Left node is null, creating new child\n");
                (*treeNode).left = &childNode;
            }
        }
        else {
            //Check if right child is null
            if((*treeNode).right != NULL){
                printf("Right node is not null, traversing...\n");
                insert((*treeNode).right, key);
            }
            else {
                printf("Right node is null, creating new child\n");
                (*treeNode).right = &childNode;
            }
        }
    }
}

void outputTree(struct node *root){
    //Traverse left
    if((*root).left != NULL){
        outputTree((*root).left);
    }
    printf("%d\n", (*root).key);
    if((*root).right != NULL){
        outputTree((*root).right);
    }
}

As of writing this question, I've just had the thought, are the child nodes being created on the stack, so when the recursive calls return, the references in the tree are pointing to a struct that no longer exists?在写这个问题时,我刚刚想到,是否在堆栈上创建了子节点,所以当递归调用返回时,树中的引用指向一个不再存在的结构?

What is wrong here?这里有什么问题?

Thank you谢谢

You create childs node on the stack by static allocation.您通过静态分配在堆栈上创建子节点。 When the insert method is finished, the child reference become invalid.当插入方法完成时,子引用变为无效。 You should use dynamic allocation with malloc.您应该对 malloc 使用动态分配。

struct node *new_node(int key, struct node *left, struct node *right) {
    struct node *this = malloc(sizeof *this);
    this->key = key;
    this->left = left;
    this->right = right;
    return this;
}

don't forget to free all of your allocations with the free function.不要忘记使用 free 函数释放所有分配。

edit : so to create the root just use编辑:所以创建根只需使用

struct node *root = new_node(-1, NULL, NULL);

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

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