C++ C++;析构函数删除内容(对象、指针?)过快

C++ C++;析构函数删除内容(对象、指针?)过快,c++,templates,destructor,C++,Templates,Destructor,我有一个任务,创建节点,并将它们插入到双链接列表中。其中一个规格是包含一个析构函数。出于某种原因,当我在main中调用addSortedList()时,我的析构函数似乎正在删除对象或指针,或者同时删除这两个对象或指针。如果我取出析构函数,程序就可以正常运行,在调用addSortedList()时程序就会崩溃。今天我甚至花了一些时间和我的导师在一起,他说我的解构器看起来很好,无法找出问题的原因。谁能向我解释一下为什么会这样 #include <iostream> using name

我有一个任务,创建节点,并将它们插入到双链接列表中。其中一个规格是包含一个析构函数。出于某种原因,当我在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
#包括
使用名称空间std;
模板
类双链接列表;
模板
类节点
{
好友类双链接列表;
公众:
Node();
节点(常数T和数据,节点*下一个,节点*上一个);
私人:
T数据;
节点*下一步;
节点*prev;
}; // 端类节点
//*******************************************************************
//为空链接列表创建标题节点。
模板
Node::Node()
{
下一个=这个;
prev=这个;
}
//*******************************************************************
//创建要插入到链接列表中的常规节点
模板
节点::节点(常量T和数据,节点*下一个,节点*上一个)
{
这->数据=数据;
这个->下一个=下一个;
此->上一个=上一个;
}
//*******************************************************************
模板
类双链接列表
{
公众:
双链接列表();
双链接列表(const T arr[],int arrSize);
~DoublyLinkedList();
无效插入(节点*插入点、常数和数据);
void display();
双链接列表addSortedList(常量双链接列表和列表2);
私人:
Node*header;//指向头节点的指针(头指向
//列表的前面和后面)
int size;//列表中的数据节点数
}; // 端类双链接列表
//*******************************************************************
//默认构造函数仅创建头节点
模板
双链接列表::双链接列表()
{
header=新节点();
尺寸=0;
}//结束构造函数
//*******************************************************************
//构造函数接受数组和数组大小,并创建双重
//带有标题节点的链接列表。
模板
双链接列表::双链接列表(const T arr[],int arrSize)
{
header=新节点();
大小=大小;
对于(int i=size-1;i>-1;i--)
{
插入(标题->下一步,arr[i]);
}
}//结束构造函数
//*******************************************************************
//析构函数在使用后删除节点。
模板
DoublyLinkedList::~DoublyLinkedList()
{
Node*oldFrontPointer;//指向要删除节点的指针
Node*newFrontPointer;//指向要删除的下一个节点的指针
oldFrontPointer=标题->下一步;
while(oldFrontPointer->next!=标题)
{
newFrontPointer=oldFrontPointer->next;
删除oldFrontPointer;
oldFrontPointer=newFrontPointer;
}
删除标题;
}//结束析构函数
//*******************************************************************
//此函数用于将新节点插入列表中
模板
void DoublyLinkedList::insert(节点*insertionPoint、常量和数据)
{
Node*prevNodePtr;//指向插入点之前的节点的指针
Node*newNodePtr;//指向新节点的指针
prevNodePtr=insertionPoint->prev;
newNodePtr=新节点(数据、插入点、prevNodePtr);
大小++;
insertionPoint->prev=prevNodePtr->next=newNodePtr;
}//结束插入
//*******************************************************************
//此函数用于打印列表中的节点数据
模板
void DoublyLinkedList::display()
{
节点*currentNodePtr=标题->下一步;
如果(大小==0)
{
下一步;
Node*list2Pointer=list2.header->next;
while(list1Pointer!=this->header&&list2Pointer->next!=list2.header)
{
//如果列表2节点小于列表1当前节点,则插入列表2节点
如果(列表1指针->数据>列表2指针->数据)
{
插入(列表1指针,列表2指针->数据);
list2Pointer=list2Pointer->next;
}
//如果列表1当前节点小于,则移动列表1指针
//列表2当前节点
else if(list1Pointer->datadata)
{
list1Pointer=list1Pointer->next;
}
//插入小于列表1当前节点的列表2节点
else if(列表1指针->下一步==此->标题)
{
插入(列表1指针,列表2指针->数据);
list2Pointer=list2Pointer->next;
}
}//结束时
//插入最后一个列表中比中最后一个节点大的2个节点
//在列表的末尾列出1
while(list1Pointer->next==this->header&&list2Pointer!=list2.header)
{
list1Pointer=list1Pointer->next;
插入(列表1指针,列表2指针->数据);
list2Pointer=list2Pointer->next;
}  
归还*这个;
}//end addSortedList
int main()
{
int arrA[]={20,80100};
int arrB[]={10,30,60100110};
int arrASize=sizeof(arrA)/sizeof(int);
int arrBSize=sizeof(arrB)/sizeof(int);
双链接列表列表a(arrA,arrASize);
双链接列表列表b(arrB,arrBSize);
双链接列表列表c;
display();
listA.display();
listB.display();//额外
列表A.addSortedList(列表B);
listA.display();
display();
}//末端总管

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

替换此项:

template <typename T>
DoublyLinkedList<T> DoublyLinkedList<T>::
   addSortedList(const DoublyLinkedList<T>& list2)
模板
双链接列表双链接列表:
addSortedList(常量双链接列表和列表2)
为此:

template <typename T>
DoublyLinkedList<T> &DoublyLinkedList<T>::
   addSortedList(const DoublyLinkedList<T>& list2)
模板
双链接列表和双链接列表::
addSortedList(常量双链接列表和列表2)

你没有遵守三条规则。克里斯说了什么。有关更多信息,请阅读此处()-你没有