使用C传递引发错误的未初始化变量

使用C传递引发错误的未初始化变量,c,memory-management,data-structures,tree,C,Memory Management,Data Structures,Tree,我有以下代码: 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->d

我有以下代码:

        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);
}
typedef结构节点
{
int数据;
结构节点*左;
结构节点*右;
}节点;
无效生成(节点*根,int i)
{
如果(i<7)
{
root=(node*)malloc(sizeof(node));
根->数据=i;
构建(根->左,2*i+1);
构建(根->右,2*i+2);
}
其他的
root=NULL;
}
无效打印(节点*根)
{
如果(根)
{
printf(“%d”,根->数据);
打印(根->左);
打印(根->右);
}
}
void main()
{
节点*树;
构建(树,0);
打印(树);
}
有两件事我不明白, 1.为什么我不能通过构建(树,0)?它说它是未初始化的,但为什么我关心它是否未初始化?我马上分配所有需要的内存,这样它就可以指向新分配的节点


如何修复此代码?谢谢你

树的
节点*
未初始化

node *tree;
这很重要,因为代码行

root = (node *)malloc (sizeof(node));
将内存分配给根目录的本地副本。一旦您离开构建的功能范围,root的副本就会超出范围。内存泄漏

记住,在C中,一切都是通过值传递的

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

void Build (node **root , int i)

该方法中的代码必须引用
*根
,而不是

您的
节点*
到树未初始化

node *tree;
这很重要,因为代码行

root = (node *)malloc (sizeof(node));
将内存分配给根目录的本地副本。一旦您离开构建的功能范围,root的副本就会超出范围。内存泄漏

记住,在C中,一切都是通过值传递的

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

void Build (node **root , int i)

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

参数是按值传递的-内存中的位置实际上没有传递。因此,当您调用Build时,您只是传入tree的值,而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);
    ...
}

参数按值传递-内存中的位置实际上没有传递。因此,当您调用Build时,您只是传入tree的值,而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);
    ...
}

但即使是本地的——那又怎样?当我完成这项功能时,它不应该消失,当然它会消失。指针按值传递,这意味着堆栈上存在指针的本地副本。。。不指向任何东西的指针。malloc将内存分配给root的本地(堆栈)副本。尝试在调试器中单步执行。但即使它是本地的-那又怎样?当我完成这项功能时,它不应该消失,当然它会消失。指针按值传递,这意味着堆栈上存在指针的本地副本。。。不指向任何东西的指针。malloc将内存分配给root的本地(堆栈)副本。尝试在调试器中单步执行。