C ++析构函数过早删除东西(对象,指针?)

时间:2013-12-05 01:31:41

标签: c++ templates destructor

我有一个创建节点的分配,并将它们插入到双向链表中。其中一个规范是包含析构函数。出于某种原因,当我在main中调用addSortedList()时,我的析构函数似乎正在删除对象或指针或两者。如果我取出析构函数,程序运行就好了,在调用addSortedList()时程序崩溃了。我今天甚至和我的导师花了一些时间,他说我的析构函数看起来很好,无法弄清楚导致问题的原因。有人可以向我解释为什么会这样吗?

#include <iostream>

using namespace std;

template <typename T>
class DoublyLinkedList;

template <typename T>
class Node
{
  friend class DoublyLinkedList<T>;

  public:
    Node();
    Node(const T& data, Node<T> *next, Node<T> *prev);

  private:
    T data;
    Node<T> *next;
    Node<T> *prev;
}; // end class Node

//*******************************************************************

// Create a header node for an empty linked list.

template <typename T>
Node<T>::Node()
{
  next = this;
  prev = this;
}

//*******************************************************************

// Create a regular node to be inserted into a linked list

template <typename T>
Node<T>::Node(const T& data, Node<T> *next, Node<T> *prev)
{
  this->data = data;
  this->next = next;
  this->prev = prev;
}

//*******************************************************************

template <typename T>
class DoublyLinkedList
{
  public:
    DoublyLinkedList();
    DoublyLinkedList(const T arr[], int arrSize);
    ~DoublyLinkedList();

    void insert(Node<T> *insertionPoint, const T& data);
    void display();
    DoublyLinkedList<T> addSortedList(const DoublyLinkedList<T>& list2);

  private:
    Node<T> *header;    // pointer to header node (header points to 
                        // front and back of list)
    int size;           // number of data nodes in list
}; // end class DoublyLinkedList

//*******************************************************************

// Default constructor creates only a header node

template <typename T>
DoublyLinkedList<T>::DoublyLinkedList()       
{
  header = new Node<T>();
  size = 0;
} // end constructor

//*******************************************************************

// Constructor takes in array and array size and creates a doubly
// linked list with a header node.

template <typename T>
DoublyLinkedList<T>::DoublyLinkedList(const T arr[], int arrSize)
{
  header = new Node<T>();
  size = arrSize;

  for (int i = size - 1; i > -1; i--)
  {
    insert(header->next, arr[i]);
  }
} // end constructor

//*******************************************************************

// Destructor to delete nodes after use.

template <typename T> 
DoublyLinkedList<T>::~DoublyLinkedList()
{
  Node<T> *oldFrontPointer; // pointer to node to be deleted
  Node<T> *newFrontPointer; // pointer to next node to be deleted

  oldFrontPointer = header->next;

  while (oldFrontPointer->next != header)
  {
    newFrontPointer = oldFrontPointer->next;
    delete oldFrontPointer;
    oldFrontPointer = newFrontPointer;
  }
  delete header;
} // end destructor


//*******************************************************************

// This function inserts a new node into a list

template <typename T>
void DoublyLinkedList<T>::insert(Node<T> *insertionPoint, const T& data)
{
  Node<T> *prevNodePtr;   // pointer to node that precedes insertionpoint
  Node<T> *newNodePtr;    // pointer to new node

  prevNodePtr = insertionPoint->prev;

  newNodePtr = new Node<T>(data, insertionPoint, prevNodePtr);
  size++;

  insertionPoint->prev = prevNodePtr->next = newNodePtr;
} // end insert

//*******************************************************************

// This function prints the node data from a list

template <typename T>
void DoublyLinkedList<T>::display()
{
  Node<T> *currentNodePtr = header->next;

  if (size == 0)
  {
    cout << "Empty linked list.";
  }
  else
  {
    while (currentNodePtr != header)
    {
      cout << currentNodePtr->data << " ";
      currentNodePtr = currentNodePtr->next;
    }
  }
  cout << "\n";
} // end display

//*******************************************************************

// This function merges the parameter list into the calling object
// list in sorted order assuming both lists are presorted.

template <typename T>
DoublyLinkedList<T> DoublyLinkedList<T>::
  addSortedList(const DoublyLinkedList<T>& list2)
{
  Node<T> *list1Pointer = this->header->next;
  Node<T> *list2Pointer = list2.header->next;

  while (list1Pointer != this->header && list2Pointer->next != list2.header)
  {
    // insert list 2 nodes if they are smaller than list 1 current node

    if (list1Pointer->data > list2Pointer->data)
    {
      insert(list1Pointer, list2Pointer->data);
      list2Pointer = list2Pointer->next;
    }

    // move list 1 pointer if list 1 current node is smaller than
    // list 2 current node

    else if (list1Pointer->data < list2Pointer->data)
    {
      list1Pointer = list1Pointer->next;
    }

    // insert list 2 nodes that are smaller than list 1 current node

    else if (list1Pointer->next == this->header)
    {
      insert(list1Pointer, list2Pointer->data);
      list2Pointer = list2Pointer->next;
    }
  }// end while

  // insert last list 2 nodes that are larger than last node in
  // list 1 at the end of the list

  while (list1Pointer->next == this->header && list2Pointer != list2.header)
  {
    list1Pointer = list1Pointer->next;
    insert(list1Pointer, list2Pointer->data);
    list2Pointer = list2Pointer->next;
  }  
  return *this;
} // end addSortedList

int main()
{
  int arrA[] = {20,80,100};
  int arrB[] = {10,30,60,100,110};
  int arrASize = sizeof(arrA)/sizeof(int);
  int arrBSize = sizeof(arrB)/sizeof(int);

  DoublyLinkedList<int> listA(arrA, arrASize);
  DoublyLinkedList<int> listB(arrB, arrBSize);
  DoublyLinkedList<int> listC;

  listC.display();
  listA.display();
  listB.display(); //extra
  listA.addSortedList(listB);
  listA.display();
  listB.display();
} // end main

1 个答案:

答案 0 :(得分:1)

您正在从addSortedList返回一个值,因此您的意图显然是返回对this的引用。返回的复制的值然后与原始对象共享内部列表指针,并使用它自己的析构函数立即删除它。

替换它:

template <typename T>
DoublyLinkedList<T> DoublyLinkedList<T>::
   addSortedList(const DoublyLinkedList<T>& list2)

用这个:

template <typename T>
DoublyLinkedList<T> &DoublyLinkedList<T>::
   addSortedList(const DoublyLinkedList<T>& list2)