使用指针和。在 C++ 中复制链表时的地址运算符

Using pointers vs. address-of operator while copying linked lists in C++

我做了如下链表结构和printList函数。两者均正常运行:

struct Node{
    int data;
    Node *np;
};

void printList(Node *x){
    cout << x->data << " ";
    if (x->np != NULL){
        printList(x->np);
    }
    return;
}

然后我决定写一个递归函数来复制链表。一个实现,返回一个指针值,工作...而另一个,返回一个地址没有工作...我无法在我的生活中弄清楚为什么会这样:

这个有效:

Node * copyList(Node *x){

    Node * y = new Node;
    y->data = x->data;
    if (x->np != NULL){
        y->np = copyList(x->np);
    }else{
        y->np = NULL;
    }
    return y;
}

这不起作用:

Node * copyList(Node *x){
    Node y = {x->data,NULL};
    if (x->np != NULL){
        y.np = copyList(x->np);
   }
   return &y;
}

我有点不明白为什么。我会假设一个指针本质上是指一个内存地址,返回 &y 就可以了...

在第二种情况下,您正在创建的节点 y 对象将在函数调用结束时超出范围。您返回的地址将无效。

一旦copyList退出,它的所有局部变量都会被销毁;在您 return 指针指向的位置不再存在 Node 对象。下次您调用函数时,该内存可能会用于其他目的。

第一个函数也是无效的,因为通常 x 的参数可以等于 NULL。所以你在 statement

中有未定义的行为
y->data = x->data;

正确的函数看起来像

Node * copyList( const Node *x )
{
    if ( x == NULL )
    {
        return NULL;
    }
    else
    {
        Node *y = new Node { x->data, copyList( x->np ) };
        return y;
    }
} 

甚至喜欢

Node * copyList( const Node *x )
{
    return ( x == NULL ) ? NULL : new Node { x->data, copyList( x->np ) };
} 

函数 printList 也存在同样的问题。它应该被定义为

void printList( const Node *x )
{
    if ( x == NULL )
    {        
        std::cout << std::endl;
    }       
    else
    {        
        std::cout << x->data << ' ';
        display( x->np );
    }        
}    

至于第二个函数,除了这个错误,它 returns 指向局部变量的指针在退出函数后变得无效,因为局部变量将被删除。