【问题标题】:Pointer to pointer doesn't work in tree copying algorithm指向指针的指针在树复制算法中不起作用
【发布时间】:2015-10-15 05:10:30
【问题描述】:

我正在尝试用 C 编写一个树复制函数:

void tree_copy(treenode *source, treenode **dest)
{
    treenode *newtree;      //the new tree will be created using this as root   
    treenode **bkup = &newtree;         //pointer to pointer, to keep backup of head of newtree

    /*
    Code to create new tree
    Traverses using *newtree
    And leaves *newtree pointing at last node created
    But *bkup still contains the address of the head node, right?
    */

    *dest = *bkup;  //assign the new tree created to the parameter
}

//I'm trying to invoke it like this:

int main(void)
{
    treenode *t1, *t2;

    create_tree(&t1);   //tested, already written function to create a tree. No bugs.
    tree_copy(t1, &t2);

    preorder(t2);       //tested, already written function for preorder traversal.
}

应该包含新创建的树的根 (t2) 的节点在此操作之后仍然保持 NULL。 为什么会这样?备份新树起始节点的逻辑有什么问题?

任何帮助将不胜感激。

【问题讨论】:

    标签: c pointers data-structures


    【解决方案1】:
    treenode *newtree;
    treenode **bkup = &newtree;
    

    bkup 包含newtree 变量的地址。 newtree 变量将包含 treenode 的地址。

    所以bkup 不包含存储在newtree 中的指针的副本,它包含newtree 变量的地址。存储它并没有真正的帮助,因为它无论如何都不会改变。 newtree 变量将保留在同一个位置,无论您为其分配什么内容。

    如果要保存newtree 的初始值的副本,则必须在初始化后将其复制到newtree* 变量中:

    treenode *root = newtree;
    ...
    *dest = root;
    

    【讨论】:

    • “所以 bkup 不包含存储在 newtree 中的指针的副本,它包含 newtree 变量的地址。存储它并没有真正的帮助,因为它无论如何都不会改变。”没错,但是如果您在代码中注意到,在返回时,我正在 取消引用 bkup。所以它现在应该提供原始newtree 节点的地址,对吧?如果我遗漏了什么,您能否编辑您的答案以显示图表?
    • bkup 包含newtree 的地址,因此取消引用它会在该地址产生该内存的内容,即newtree 变量的内容。 *bkup 仅表示“在newtree 变量中查看那里”。它将为您提供该变量的当前内容,而不是它的某些旧版本。如果您为newtree 分配新内容,则其内存位置中的内容会发生变化,如果您再次使用*bkup 查看内存位置,您将看到新内容。 bkup == &newtree,所以*bkup == *&newtree (== newtree)
    • 啊,明白了。感谢您的回答和解释。
    【解决方案2】:
     treenode *newtree;      //the new tree will be created using this as root   
        treenode **bkup = &newtree;         //pointer to pointer, to keep backup of head of newtree //
    

    newtree 是一个未初始化的指针,您正在使用未初始化变量的地址,这将导致未定义的行为

    【讨论】:

    • 感谢您的回答,但我不明白这一点。我已将newtree地址 存储在bkup 中。现在我开始创建一个以newtree 为头的新树。所以现在*bkup 应该包含新树的头部,对吧?
    • 我不认为获取未初始化变量的地址是未定义的行为。参见例如stackoverflow.com/questions/28587022/…
    猜你喜欢
    • 2015-06-17
    • 2018-04-22
    • 2010-10-27
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 2011-08-04
    • 2010-09-27
    相关资源
    最近更新 更多