使用 malloc 函数的指向数据不断消失在它之外

pointed data in function with malloc keeps disappearing outside of it

我创建了两个结构

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

typedef struct head
{
    int count;
    struct node* root;
} head;

这是我试图用来将数据插入树中的函数。

int insert(struct node* root, int value)
{
    node* newnode =(node*)malloc(sizeof(node));
    newnode->data=value;
    newnode->left=NULL;
    newnode->right=NULL;
    if(root==NULL)
    {
        root=newnode;
        return 1;
    }
    if(value<root->data)
    {
        if(root->left==NULL)
        {
            root->left=newnode;
            return 1;
        }
        else
        {
            return insert(root->left,value);
        }
    }
    else if(value==root->data)
    {
        printf("data already exist\n");
        free(newnode);
        return 0;
    }
    else
    {
        if(root->right==NULL)
        {
            root->right=newnode;
            return 1;
        }
        else
        {
            return insert(root->right,value);
        }
    }
}

当我操作时

head* BSThead=(head*)malloc(sizeof(head));
insert(BSThead->root,10);

看到insert函数成功进入第一个if,运行root=newnode;这一行,看到给的地址

但是当这个函数结束时,我回到主函数来访问它 printf("%d",BSThead->root);

这一行只打印 0,我认为这意味着 BST->root 当前为空。

据我所知,malloc 函数创建的数据与普通值不同,其作用域超出了它的函数范围。所以我想虽然 newnode 是在插入函数中创建的,但当插入函数结束时不会像普通变量那样被销毁,因此我可以在程序运行时一直使用它。

这些行:

if(root==NULL)
{
    root=newnode;
    return 1;
}

在函数中修改 root 但不要在调用函数中更改同一变量的值。

调用函数中 root 的值继续为 NULL,并且您泄漏了调用 malloc.

分配的每个节点

解决此问题的一种方法是将指针传递给 root

int insert(struct node** root, int value)
{
    ...
    if(*root==NULL)
    {
       *root=newnode;
       return 1;
    }

   ...
}

并调用该函数使用:

insert(&(BSThead->root),10);

一个问题是您正在使用:

head* BSThead = (head*)malloc(sizeof(head));
insert(BSThead->root, 10);

这会将指向未初始化数据的未经检查的指针传递给函数。只有当你不走运时,你传递的才会是空指针。该函数无法修改 BSThead->root 中的值,因为您传递的是它的值,而不是指向它的指针。您也没有传递整个 head 结构,因此 insert() 代码无法更新计数。

您需要在使用前初始化您的头部结构。当您使用它时,您需要将指向 head 结构的指针传递给函数,或者您需要将 root 成员的地址传递给函数以便函数可以更新它:

head* BSThead = (head*)malloc(sizeof(head));
if (BSThead != 0)
{
    BSThead->count = 0;
    BSThead->root = 0;
    /* Either */
    insert(BSThead, 10);         // And insert can update the count
    /* Or */
    insert(&BSThead->root, 10);  // But insert can't update the count!
    …use the list…
    …free the list…
}