C 使用双指针复制LinkedList

C 使用双指针复制LinkedList,c,C,受此启发,我尝试复制带有双指针(指针到指针)的LinkedList 定义 typedef struct MyNode MyNode; struct MyNode { int value; MyNode *next; } 实施 MyNode *CreateNode(int value) { MyNode *node = malloc(sizeof(MyNode)); node->value = value; node->next = NULL

受此启发,我尝试复制带有双指针(指针到指针)的LinkedList

定义

typedef struct MyNode MyNode;

struct MyNode {
    int value;
    MyNode *next;
}
实施

MyNode *CreateNode(int value) {
    MyNode *node = malloc(sizeof(MyNode));
    node->value = value;
    node->next = NULL;
    return node;
}


int main() {
    MyNode *an_existing_list = CreateNode(1); // edit, source list
    an_existing_list->next = CreateNode(2);
    an_existing_list->next->next = CreateNode(3);


    MyNode *cursor = an_existing_list; // an existing list as a source


    MyNode **previous = NULL; // double pointer reference

    while (cursor) { // iterate the exisitng list

        MyNode *temp = CreateNode(cursor->value); // create a new node  

        if (previous) { // if a node was created in the previous iteration
            (*previous)->next = temp; // access the actual node and set previous' next to this new node
        }

        previous = &temp; // for the next iteration

        cursor = cursor->next; // next node
    }
    return 0;
}

问题:我在下一个->下一个->下一个-/p>中遇到了一些相同节点的无休止副本。评论员已经指出了你的错误:你试图在列表链接中保存局部变量的地址。该局部变量在while循环体结束后不在作用域内,即imemidually。这意味着您的程序调用未定义的行为,在您的情况下是一个无止境的循环

但是您也没有理解本文的要点:您使用指向节点指针的指针,以便不必将头指针为null的情况视为特殊情况。换句话说,您不需要
previous
。指向指针
p
的指针已经处理了指向新节点的链接存储在何处的问题,即位于
*p
,其中

  • (a)开头的列表标题地址,以及
  • 在(b)之后的前一个节点的
    下一个
    字段的地址
您的复制函数应如下所示:

MyNode *duplicate(const MyNode *cursor)
{
    MyNode *dup = NULL;
    MyNode **p = &dup;                  // (a)

    while (cursor) {
        *p = create(cursor->value);

        p = &(*p)->next;                // (b)
        cursor = cursor->next;
    }

    return dup;
}

请看。

评论者已经指出了您的错误:您试图在列表链接中保存局部变量的地址。该局部变量在while循环体结束后不在作用域内,即imemidually。这意味着您的程序调用未定义的行为,在您的情况下是一个无止境的循环

但是您也没有理解本文的要点:您使用指向节点指针的指针,以便不必将头指针为null的情况视为特殊情况。换句话说,您不需要
previous
。指向指针
p
的指针已经处理了指向新节点的链接存储在何处的问题,即位于
*p
,其中

  • (a)开头的列表标题地址,以及
  • 在(b)之后的前一个节点的
    下一个
    字段的地址
您的复制函数应如下所示:

MyNode *duplicate(const MyNode *cursor)
{
    MyNode *dup = NULL;
    MyNode **p = &dup;                  // (a)

    while (cursor) {
        *p = create(cursor->value);

        p = &(*p)->next;                // (b)
        cursor = cursor->next;
    }

    return dup;
}

查看它。

temp
在堆栈上。在
previous
中保存指向它的指针将导致未定义的行为。我知道,我尝试在while循环之外声明
My*temp
,并且光标指向要复制的源链接列表。是的,请发布一个。使用现有列表编辑,是否还有其他内容可以添加?我想代码现在已经完成了。
temp
在堆栈上。在
previous
中保存指向它的指针将导致未定义的行为。我知道,我尝试在while循环之外声明
My*temp
,并且光标指向要复制的源链接列表。是的,请发布一个。使用现有列表编辑,是否还有其他内容可以添加?我想代码现在已经完成了。这里:
previous=&temp极好@你的LinkedList版本甚至比这篇文章还要短。您在大多数函数中单独使用双指针。@AppDeveloper:是的。这是一种有用的技术。它有助于简洁的代码,也适用于其他链接结构,如树极好@你的LinkedList版本甚至比这篇文章还要短。您在大多数函数中单独使用双指针。@AppDeveloper:是的。这是一种有用的技术。它有助于简洁的代码,并可与其他链接结构(如树)一起使用。