简体   繁体   English

使用迭代插入函数在第二次插入后初始化二叉搜索树时出现分段错误

[英]Segmentation fault in inititalizing a binary search tree after second insertion using a iterative insert function

I'm getting a segmentation fault after trying to insert a second node into the tree, a segmentation fault is thrown.在尝试将第二个节点插入树后,我遇到了分段错误,抛出了分段错误。 Is the segmentation fault due to the initialize function or insert ?是由于initialize函数还是insert导致的分段错误? And how do I solve it by making changes in server.c?我如何通过在 server.c 中进行更改来解决它?

client.c file:客户端.c文件:

int main()
{
    Tree my_tree;
    initialize(&my_tree);
    while(1)
    {
        scanf("%d", &choice);
        switch (choice)
        {
        case 1:
            scanf("%d", &element);
            insert(&my_tree, element);
            break;
        case 2:
               exit(0);
       }
    }
    return 0;
}

server.c file server.c 文件


typedef struct node
{
    int data;
    struct node *left;
    struct node *right;
} Node;

typedef struct tree
{
    Node *root;
} Tree;

void initialize(Tree *tree)
{
    tree = (Tree*)malloc(sizeof(Tree));
    tree->root = NULL;
}

void insert(Tree *tree, int data)
{
    Node *temp = (Node*)malloc(sizeof(Node));
    temp->left = temp->right = NULL;
    temp->data = data;
    if(tree->root == NULL) 
        tree->root = temp;    
    else
    {
        Node *prev,*curr;
        prev = NULL;
        curr = tree->root;
        while(curr != NULL)
        {
            if(temp->data < curr->data){
                prev = curr;
                curr = curr->left;
            }
            if(temp->data >curr->data){
                prev = curr;
                curr = curr->right;
            }
        }
        if(temp->data < prev->data)
            prev->left = temp;
        if(temp->data > prev->data)
            prev->right = temp;
    }
}
void initialize(Tree *tree)
{
    tree = (Tree*)malloc(sizeof(Tree));
    tree->root = NULL;
}

Change to改成

void initialize(Tree *tree)
{
    if (tree) {
     tree->root = NULL;
    }
}

When you allocate memory to tree you are making it to point new memory location, thus your original tree 's root node will not be initialized to NULL and also you introduce memory leaks.当您为tree分配内存时,您将使其指向新的内存位置,因此您的原始tree的根节点不会被初始化为NULL并且您还会引入内存泄漏。

Instead of initializing the Tree object you actually use in your program ( tree in main), you allocate a new Tree object and initialize that object.不是初始化您在程序中实际使用的Tree对象( main 中的tree ),而是分配一个新的Tree对象并初始化该对象。 Effectively, initialize doesn't do anything but leak memory.实际上, initialize除了泄漏内存之外什么都不做。

To fix this, replace要解决此问题,请更换

void initialize(Tree *tree)
{
    tree = (Tree*)malloc(sizeof(Tree));
    tree->root = NULL;
}

with

void initialize(Tree *tree)
{
    tree->root = NULL;
}

The OP points out there's a second error. OP指出还有第二个错误。 This where I point out that one shouldn't be depending on the kindness of strangers, and learn how to debug such problems.在这里我指出一个人不应该依赖陌生人的好意,并学习如何调试此类问题。

You could use a debugger.您可以使用调试器。

$ gcc -Wall -Wextra -pedantic -g a.c -o a && gdb --args ./a
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
...
(gdb) r
Starting program: /tmp/ikegami/a
1
3
1
2

Program received signal SIGSEGV, Segmentation fault.
0x00005555555547b1 in insert (tree=0x7fffffffdda0, data=2) at a.c:39
39                  if(temp->data >curr->data){
(gdb) print temp
$1 = (Node *) 0x555555756690
(gdb) print curr
$2 = (Node *) 0x0
(gdb) quit
A debugging session is active.

        Inferior 1 [process 1433] will be killed.

Quit anyway? (y or n) y

Another approach would be to use -fsanitize=address when compiling the program.另一种方法是在编译程序时使用-fsanitize=address

$ gcc -Wall -Wextra -pedantic -g -fsanitize=address a.c -o a && ./a
1
3
1
2
ASAN:DEADLYSIGNAL
=================================================================
==1370==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x556253e76e87 bp 0x7ffe3a28e390 sp 0x7ffe3a28e360 T0)
==1370==The signal is caused by a READ memory access.
==1370==Hint: address points to the zero page.
    #0 0x556253e76e86 in insert /home/ikegami/tmp/a.c:39
    #1 0x556253e771af in main /home/ikegami/tmp/a.c:64
    #2 0x7fc3bdadcb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #3 0x556253e76b29 in _start (/tmp/ikegami/a+0xb29)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ikegami/tmp/a.c:39 in insert
==1370==ABORTING

But approach show that temp->data >curr->data is the culprit.但是方法表明temp->data >curr->data是罪魁祸首。 Using the debugger, we saw that curr is NULL , so curr->data is at issue.使用调试器,我们看到currNULL ,所以curr->data是有问题的。 Now you know that you need figure out if why curr is NULL when you don't expect it to be.现在您知道您需要弄清楚为什么curr在您不希望它是 NULL 时为 NULL。

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

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