【问题标题】:passing an uninitialized variable throwing an error using C使用 C 传递未初始化的变量引发错误
【发布时间】:2012-07-18 23:27:35
【问题描述】:

我有这个代码:

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

void Build (node *root , int i)
{
        if (i < 7)
    {
        root = (node *)malloc (sizeof(node));
        root->data = i;
        Build(root->left,2*i+1);
        Build(root->right,2*i+2);
    }
    else
        root = NULL;
}
void Print (node *root)
{
    if (root)
    {
        printf ("%d  ",root->data);
        Print(root->left);
        Print(root->right);
    }
}
void main()
{
    node *tree;

    Build(tree,0);
    Print(tree);
}

两件事我不明白, 1. 为什么我不能通过 Build(tree,0) ?它说它未初始化,但为什么我要关心它是否未初始化?我将立即分配所有需要的内存,因此它将指向新分配的节点。

如何修复此代码?谢谢!!!

【问题讨论】:

    标签: c memory-management data-structures tree


    【解决方案1】:

    您的 node * 到树未初始化。

    node *tree;
    

    这很重要,因为代码行

    root = (node *)malloc (sizeof(node));
    

    将内存分配给 root本地副本。一旦离开 Build 的函数范围,root 的副本就会超出范围。内存泄漏。

    请记住,C 中的所有内容都是按值传递的。

    如果你真的希望 Build 分配内存,签名必须是

    void Build (node **root , int i)
    

    并且您在该方法中的代码必须引用 *root 而不是 root

    【讨论】:

    • 但即使它是本地的 - 那又如何?当我完成函数时它不应该消失
    • 当然可以。指针是按值传递的,这意味着堆栈上有指针的本地副本......一个指向任何内容的指针。您的 malloc 将内存分配给 root 的本地(堆栈)副本。尝试在调试器中单步执行。
    【解决方案2】:

    参数是按值传递的——实际上并没有传递内存中的位置。所以当你调用 Build 时,你只是传入了 tree 的值,而它恰好是未初始化的。 Build 函数使用该值创建一个局部根变量 - 当您在 Build 中设置 root = ... 时,您将用新值覆盖该未定义值,但该新值仍然只是在局部根变量中 - 它是main 中的树变量从未见过。

    你真正想做的是让 Build 返回新创建的树指针:

    node * Build(int i)
    {
        node *root;
        ...
            root->left = Build(2*i+1)
        ...
        return root;
    }
    
    void main() 
    {
        ...
        tree = Build(0);
        ...
    }
    

    【讨论】:

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