简体   繁体   English

AVL树插入导致段故障

[英]AVL Tree Insertion Causes Seg Fault

I've been trying to implement the rotation functions in my AVL program and I continue to get a seg fault when the Right Rotate function is called. 我一直在尝试在AVL程序中实现旋转功能,并且在调用Right Rotate函数时继续出现段错误。 I performed a Valgrind test and there are 3 errors that I get: 我执行了Valgrind测试,发现3个错误:

==23399== 1 errors in context 1 of 3:
==23399== Invalid read of size 4
==23399==    at 0x8048C3A: insert (avltree.c:190)
==23399==    by 0x80488B6: main (avltree.c:85)
==23399==  Address 0x3 is not stack'd, malloc'd or (recently) free'd
==23399== 
==23399== 
==23399== 1 errors in context 2 of 3:
==23399== Use of uninitialised value of size 4
==23399==    at 0x8048C3A: insert (avltree.c:190)
==23399==    by 0x80488B6: main (avltree.c:85)
==23399==  Uninitialised value was created by a stack allocation
==23399==    at 0x8048723: main (avltree.c:42)
==23399== 
==23399== 
==23399== 1 errors in context 3 of 3:
==23399== Conditional jump or move depends on uninitialised value(s)
==23399==    at 0x8048C03: insert (avltree.c:182)
==23399==    by 0x80488B6: main (avltree.c:85)
==23399==  Uninitialised value was created by a stack allocation
==23399==    at 0x8048723: main (avltree.c:42)

It mentions in two of the errors that there is an uninitialized value. 它在两个错误中提到存在一个未初始化的值。 I think it has something to do with me swapping values of the left and right sub-trees, but I cannot seem to pinpoint exactly where things are going wrong. 我认为这与我交换左右子树的值有关,但是我似乎无法确切指出出问题的地方。

Here is my Right Rotate function: 这是我的“ 右旋转”功能:

void rightRotate(node * y)
{
    /* Assign values */
    node *x = y->left;
    node *subTree = x->right;

    /* Perform rotation */
    x->right = y; /* x is now root */
    y->left = subTree;

    /* Update heights */
    y->height = max(height(y->left), height(y->right))+1;
    x->height = max(height(x->left), height(x->right))+1;
}

And the way it's all inserted is with the Insertion function: 所有插入的方式都是使用Insertion函数:

void insert(node ** tree, node * item)
{
    int balanceNum;

    /* If no root, item is root */
    if(!(*tree)) {
        *tree = item;
        printf("Root: \n"); /*Every node seems to get printed here */
        (*tree)->height = 0;
        return;
    }

    if(strcmp(item->key,(*tree)->key) < 0) {
        insert(&(*tree)->left, item);
    }
    else if(strcmp(item->key,(*tree)->key) > 0) {
        insert(&(*tree)->right, item);
    }
    else if(strcmp(item->key,(*tree)->key) == 0) {
        (*tree)->frequency++;
    }

    /* Update height of ancestor node */
    (*tree)->height = max(height((*tree)->left), height((*tree)->right)) + 1;
    printf("%s Height: %d\n", (*tree)->key, (*tree)->height);

    balanceNum = balance(*tree);

    if(balanceNum > 1 && strcmp(item->key,(*tree)->left->key) < 0) {
        printf("Right Rotate! Balance: %d with %s\n", balanceNum, item->key);
        rightRotate(*tree);
    }
}

I removed the rest of my rotate functions for the sake of this specific situation. 为了这种特殊情况,我删除了其余的旋转功能。 Could someone point out where I may have gone wrong with my rotate function? 有人可以指出我的旋转功能可能出问题了吗?

Thank you so much for any suggestions or tips. 非常感谢您的任何建议或提示。

EDIT: I updated my valgrind postings to include the line numbers of my code. 编辑:我更新了valgrind发布以包括我的代码的行号。

This is because every time you insert a function, the following codes are executed: 这是因为每次插入函数时,都会执行以下代码:

   if(!(*tree)) {
        *tree = item;
        printf("Root: \n"); /*Every node seems to get printed here */
        (*tree)->height = 0;
        return;
    }

The reason is that insert() is called recursively. 原因是insert()被递归调用。

if(strcmp(item->key,(*tree)->key) < 0) {
    insert(&(*tree)->left, item);
}
else if(strcmp(item->key,(*tree)->key) > 0) {
    insert(&(*tree)->right, item);
}
else if(strcmp(item->key,(*tree)->key) == 0) {
    (*tree)->frequency++;
}

&(*tree)->left can be NULL. &(* tree)-> left可以为NULL。 Supposing only a root is in the tree currently, its left and right are NULL pointers. 假设当前树中只有一个根,则其左和右为NULL指针。 An insertion seems to will bypass the if(!(*tree)). 插入似乎将绕过if(!(* tree))。 However it will call either insert(&(*tree)->left, item) or insert(&(*tree)->right, item), both of them have a NULL pointer as its first parameter. 但是,它将调用insert(&(* tree)-> left,item)或insert(&(* tree)-> right,item),它们两个都将NULL指针作为其第一个参数。

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

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