【问题标题】:pointed data in function with malloc keeps disappearing outside of itmalloc 函数中的指向数据不断消失在它之外
【发布时间】:2015-08-03 22:19:58
【问题描述】:

我创建了两个结构

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 是在插入函数中创建的,但不会像普通变量一样在插入函数结束时被破坏,因此我可以在程序运行时一直使用它。

【问题讨论】:

  • 您可能需要将指向根节点的指针传递给函数。或者您可以从函数返回新的根节点指针。 SO上有许多具有相同基本诊断的问题。但是,您还将未经检查的、未初始化的数据从 malloc() 传递给函数,这也会导致很多麻烦。

标签: c pointers malloc


【解决方案1】:

一个问题是你正在使用:

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

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

您需要在使用前初始化头部结构。当您使用它时,您需要将指向头结构的指针传递给函数,或者您需要将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…
}

【讨论】:

    【解决方案2】:

    这些行:

    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);
    

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2014-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多