C++ 链接列表队列实现和析构函数错误:"Aborted (Core Dumped)"

C++ LinkedList Queue Implementation and Destructor Error:"Aborted (Core Dumped)"

本文关键字:Aborted Core Dumped 错误 列表 链接 队列 实现 析构函数 C++      更新时间:2023-10-16

我正在尝试了解C++,但我在内存管理和析构函数的概念方面遇到了问题。我尝试使用链表编写队列实现,当我尝试在析构函数方法(粗体)中删除链表节点时收到"中止(核心转储)"错误消息。如果有人知道我做错了什么,请告诉我!

这是我的析构函数方法的代码:

template <class T>
Queue<T>::~Queue(){
  Node<T> *currHead = head;
  while(currHead != NULL){
    Node<T> *nextHead = currHead->next;
    delete currHead;
    currHead = nextHead;
  }
  Node<T> *currTail = tail;
  while(currTail != NULL){
    Node<T> *nextTail = currTail->next;
    delete currTail;
    currTail = nextTail;
  }
}

作为参考,这是我的完整链接列表队列实现:

template <class T>
class Node{
public:
  T data;
  Node<T> *next=NULL;
};
template <class T>
class Queue{
public:
  Queue();
  ~Queue();
  void push(T);
  T pop();
  int size=0;
  Node<T> *head=NULL;
  Node<T> *tail=NULL;
};
template <class T>
Queue<T>::Queue(){}
template <class T>
Queue<T>::~Queue(){
  Node<T> *currHead = head;
  while(currHead != NULL){
    Node<T> *nextHead = currHead->next;
    delete currHead;
    currHead = nextHead;
  }
  Node<T> *currTail = tail;
  while(currTail != NULL){
    Node<T> *nextTail = currTail->next;
    delete currTail;
    currTail = nextTail;
  }
}
template <class T>
void Queue<T>::push(T data){
  Node<T> *node = new Node<T>;
  node->data = data;
  if(head == NULL){
    head = node;
  }else{
    tail->next = node;
  }
  tail = node;
  size++;
}
template <class T>
T Queue<T>::pop(){
  if(size == 0){
    throw "Empty Queue";
  }else{
    Node<T> *oldHead = head;
    T oldData = oldHead->data;
    head = head->next;
    size--;
    delete oldHead;
    return oldData;
  }
}

编辑:

我也尝试了析构函数的以下定义,但遇到了同样的错误:

template <class T>
Queue<T>::~Queue(){
  while(head != NULL){
    Node<T> *currHead = head;
    head = head->next;
    delete currHead;
  }
  while(tail != NULL){
    Node<T> *currTail = tail;
    tail = tail->next;
    delete currTail;
  }
}

在析构函数的第一部分中,您将删除从 head 开始的所有列表项。在析构函数的第二部分中,您尝试使用保留在尾部的指针再次删除最后一个列表项,但它已在第一部分中被删除。

删除指针不会更改指针或指向已删除内存的任何其他指针:

#include <iostream>
int main() {
    int* head = new int[4];
    int* tail = head;
    delete head;
    std::cout << "head = " << (void*)head << ", tail = " << (void*)tail << "n";
}

你的代码应该是:

template<typename T>
Queue<T>::~Queue(){
  Node<T> *currHead = head;
  while(currHead != nullptr){
    Node<T> *nextHead = currHead->next;
    delete currHead;
    currHead = nextHead;
  }
  head = tail = nullptr;
  size = 0;
}

或者,如果您的 pop 功能有效:

template<typename T>
Queue<T>::~Queue() {
    while (size)
        pop();
}