【问题标题】:Using pointers vs. address-of operator while copying linked lists in C++ [duplicate]在 C++ 中复制链表时使用指针与地址运算符 [重复]
【发布时间】:2015-06-23 21:39:30
【问题描述】:

我做了如下链表结构和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 就可以了...

【问题讨论】:

  • 取决于您的编译器,如果您打开警告,它应该能够准确地告诉您为什么这不起作用。

标签: c++ pointers linked-list singly-linked-list


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      第一个函数也是无效的,因为通常x 的参数可以等于NULL。所以你在声明中有未定义的行为

      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 );
          }        
      }    
      

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

      【讨论】:

        猜你喜欢
        • 2011-06-30
        • 1970-01-01
        • 1970-01-01
        • 2017-02-08
        • 2016-06-04
        • 1970-01-01
        • 2017-09-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多