【问题标题】:Implementing a linked list: head insertion and destructor实现链表:头部插入和析构函数
【发布时间】:2013-09-12 12:25:53
【问题描述】:

我已经这样做了:

class Node {
  //
  int key;
  Node* next;

public:

  //
  Node() : key( -1 ), next( NULL ) {}
  Node( int i, Node* j ) : key( i ), next( j ) {}
  //
  ~Node() { delete next; }

  //
  static void head_insertion( Node* & head, int i );
  void print_list();
};


void Node::head_insertion( Node* & head, int i ) {


  cout << "insert() 1 head = " << head << endl; 
  // append the current list to n
  Node n(i, head);
  cout << "address of n = " << &n << endl;
  // make n the new head
  head = &n;
  //

  cout << "insert() 2 head = " << head << endl; 
}

头部插入不起作用:

insert() 1 head = 0x7fff56821518
address of n = 0x7fff56821518
insert() 2 head = 0x7fff56821518
Segmentation fault: 11

我有两个问题:

  • head_insertion中新创建的节点nhead指向的地址相同。发生了什么事?
  • 我编写析构函数时认为会递归调用列表中下一个元素的析构函数。这是正确的吗?

【问题讨论】:

  • 您正在将一个本地实例变量“添加”到您的列表中。需要动态分配一个新的Node;不推送本地范围的实例。一旦离开该范围,该对象就消失了,访问它是未定义的行为
  • 你如何调用 head_insertion()

标签: c++ linked-list destructor


【解决方案1】:

您没有使用动态内存来分配n。在第一次通过时,它被添加到列表中,然后函数结束并且n 超出范围。在第二遍时,它恰好出现在堆栈上的相同位置,产生相同的指针

【讨论】:

    【解决方案2】:

    void Node::head_insertion( Node* &amp; head, int i )中的代码:

    Node n(i, head);
    cout << "address of n = " << &n << endl;
    // make n the new head
    head = &n;
    

    应该是:

    Node *pn = new Node(i, head);
    cout << "address of n = " << pn << endl;
    // make n the new head
    head = pn;
    

    而析构函数~Node() { delete next; }导致链接断开,应该避免。

    还有更多... 整个设计引起了问题。

    你的类是为了实现一个Node,所以做一个Node应该做的。

    class Node {
      int key;
      Node* next;
    
    public:
    
      Node() : key( -1 ), next( NULL ) {}
      Node( int i, Node* j ) : key( i ), next( j ) {}
      //
      ~Node() { }   // don't delete the next node here! Not the job of this object.
    
    
      void print_node();
    };
    
    class Linklist {
        Node *head;
    public:
        Linklist(): head(0) {}
        static void head_insertion( Linklist & list, int i );
        void print_list();
        〜Linklist();       // traverse your list node and do the deletion here
    }
    

    把应该由列表级完成的事情交给类Linklist来处理。

    【讨论】:

      【解决方案3】:

      在函数void Node::head_insertion( Node* &amp; head, int i ) 中,您正在创建一个自动变量Node n(),其生命周期在函数范围内,因此在head_insertion 函数之外,如果您想访问该节点,您将获得segmentation fault,因为该内存区域你不再拥有。 为防止您可能动态创建对象:

      Node* n = new Node(i,head)
      

      关于您的最后一个问题:即使您不编写自己的析构函数,编译器也会为您提供默认版本。我猜析构函数没有调用析构函数,所以为什么要递归。

      【讨论】:

        猜你喜欢
        • 2015-08-03
        • 2020-07-19
        • 2012-10-15
        • 2016-12-08
        • 2021-02-07
        • 1970-01-01
        • 2013-04-26
        • 1970-01-01
        相关资源
        最近更新 更多