【问题标题】:Binary Search Tree in C causing a Heap Corruption ErrorC中的二叉搜索树导致堆损坏错误
【发布时间】:2021-08-10 20:03:42
【问题描述】:

所以我是一名 Python 程序员,我正在尝试自学 C。就像练习一样,我一直在尝试用 C 实现一个简单的二叉搜索树。我从来不需要处理内存分配或之前的指针,它导致了很多错误。

我的程序一直给我退出代码 -1073740940 (0xC0000374),我理解这意味着堆已损坏。这是一个有点长的程序,所以我只包含了有问题的函数。

使用 for 循环重复调用此插入函数,以将数组的内容插入二叉搜索树。数组的内容是5、4、6、3、7、2、8、1、9、0(目的是让树平衡)。

所以函数首先有 5 个传递给它。 pBST->listRoot 调用的指针为NULL(pBST 是一个指向列表结构的指针),所以插入5 作为根节点。这工作正常。然后将 4 传递给函数。由于已经有一个根,它会检查该根的子节点。 4 小于 5,所以检查 5 的左孩子。 5 的左子节点的指针为空,因此它尝试将 4 作为新节点插入。这是导致程序崩溃的那一行:

struct Node* pTemp = calloc(1, sizeof(struct Node));

我尝试了这行的几个变体。这是踢球者:cLion 的调试器无法重现这一点。当我通过调试器运行它时,它工作得很好。我认为这与调试器每次使用相同的内存地址以实现可重复性这一事实有关。我留下了调试 printf 语句并添加了 Node 和 binarySearchTree 结构的代码。

typedef struct Node BSTNode;

struct Node {
    BSTNode* parent;
    BSTNode* left;
    BSTNode* right;
    int* data;
};



typedef struct {
    BSTNode* listRoot;
    int nodeCount;
} binarySearchTree;
void insert(int Value, binarySearchTree* pBST) {
/*
 * This function
 */

//====DEBUG CODE============
int debugIterations = 0;
printf("Now inserting %d \n", Value);
//=====END DEBUG CODE=======


//if no root, make it the root
if (pBST->listRoot == NULL) {

    struct Node* newNode = calloc(1, sizeof(binarySearchTree));
    (*pBST).listRoot = newNode;

    (*pBST).listRoot->data;

    (*pBST).listRoot->data = Value;
    //pBST->listRoot->data = Value;

    pBST->listRoot->parent = NULL;

    pBST->listRoot->right = NULL;
    pBST->listRoot->left = NULL;

    return;
} else {
    struct Node* pCursor = pBST->listRoot;

    while (1){

        printf("Iterations: %d \n", debugIterations);
        debugIterations++;


        //Check if the number is the same
        if (pCursor->data == Value){
            printf("ERROR: Tried to insert duplicate value into tree");
            return;
        }

        //Is the value > the node?
        else if (pCursor->data < Value) {

            //DEBUG
            printf("== check succeeded, now value > data\n");


            // Is the value a Null?
            if (pCursor->right == NULL) {

                //DEBUG
                printf("Running function to insert %d as a new node to the right\n", Value);

                //If yes, then insert the value as a nul

                //Create Node
                struct Node* pTemp = calloc(1, sizeof(binarySearchTree));
                pTemp->data = Value;
                pTemp->parent = pCursor;
                pCursor->right = pTemp;
                pTemp->left = NULL;
                pTemp->right = NULL;

                return;
            }

            //If no, then iteravely continue.
            else {

                printf("Iteravely continuing to the right");

                pCursor = pCursor->right;
                continue;
            }

        }

        //Is the value < the root?
        else {

            //DEBUG
            printf("== check succeeded, now value < data\n");



            //Is the value a Null?
            if (pCursor->left == NULL) {

                //DEBUG
                printf("Running function to insert %d as a new node to the left\n", Value);




                //If yes, then insert the value where the null is.
                //Create Node

                struct Node* pTemp = (struct Node*)calloc(1, sizeof(struct Node));

                printf("Successfully declared and allocated memory");

                pTemp->data = Value;
                pTemp->parent = pCursor;
                pCursor->left = pTemp;
                pTemp->left = NULL;
                pTemp->right = NULL;

                return;
            }

            //If no, then iteravely continue
            else{

                printf("Iteravely continuing to the right");

                pCursor = pCursor->left;
                continue;
            }

        }

    }

}

}

【问题讨论】:

  • struct Node* newNode = calloc(1, sizeof(binarySearchTree)); 看起来很奇怪,应该不是sizeof(Node)
  • 值得注意的是,GeeksForGeeks 对二叉树进行了广泛的处理与源代码,以便您可以比较笔记。 geeksforgeeks.org/binary-tree-data-structure
  • 您没有收到带有单独行 (*pBST).listRoot-&gt;data; 的编译器警告吗?我建议你删除它...

标签: c memory struct heap-corruption


【解决方案1】:

线

struct Node* pTemp = calloc(1, sizeof(binarySearchTree));

错了。结构体binarySearchTree 有一个指针和一个int,但结构体struct Node 有4 个指针,所以struct Node 应该大于binarySearchTree,这样分配的空间会比需要的少,导致out-of -范围访问。

应该是:

struct Node* pTemp = calloc(1, sizeof(*pTemp));

struct Node* pTemp = calloc(1, sizeof(struct Node));

另外,将数据int Value 存储在成员int* data;(*pBST).listRoot-&gt;data = Value; 中看起来很奇怪。看起来该成员应该是int,而不是int*

【讨论】:

  • BSTNode* 而不是struct Node*
  • 感谢您的帮助。不幸的是,我修复了它,它没有做任何事情。程序仍然崩溃。
  • 我的两分钱:应该是struct Node* pTemp = calloc(1, sizeof(struct Node));。为节点保留空间,而不是为节点指针。
  • @Zilog80 谢谢,已修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 2013-04-15
  • 2021-02-21
相关资源
最近更新 更多