模板化的出列无效指针:删除类时失败

Templated Dequeue invalid pointer: Fails on deleting class

本文关键字:删除 失败 指针 无效      更新时间:2023-10-16

我的模板队列的出列函数对于字符串队列来说很好,但如果我使用自定义Robot类,它在尝试删除指针时会崩溃。我很好奇为什么。

例如,在main.cpp 中

#include <iostream>
#include <cstdlib>
#include <cstring>
#include "robotqueue.h"
#include "robotcustomer.h"
#include "servicestation.h"
using namespace std;
int main()
{
    //- TEST ONE: QUEUE<STRING> -//
    RobotQueue < string > stringQueue;
    string a("Tim");
    string b("Greg");
    stringQueue.enqueue(a);
    stringQueue.enqueue(b);
    stringQueue.dequeue();
    stringQueue.dequeue();
    //- TEST TWO: QUEUE<RobotCustomer> -//
    RobotQueue < RobotCustomer > robotQueue;
    RobotCustomer e("Tim",3);
    RobotCustomer f("Greg",5);
    robotQueue.enqueue(e);
    robotQueue.enqueue(f);
    robotQueue.dequeue();            <--- Segfault occurs here
    robotQueue.dequeue();
    return 0;
}

字符串队列工作正常,但我得到了这个错误:

***Error in `q': munmap_chunk(): invalid pointer: 0x0000000001d6c108 ***
Aborted (core dumped)

我的模板队列看起来像这样(不知道你是否需要更多)。

robotqueue.hpp

// Default Constructor
template <typename T>
RobotQueue<T>::RobotQueue()
{
    m_size = 0;
    m_front = NULL;
    m_back = NULL;
}
// Default destructor
template <typename T>
RobotQueue<T>::~RobotQueue() 
{
    Node<T>* currNode = m_front, *nextNode = NULL;
    while ( currNode != NULL )
    {
        nextNode = currNode->m_next;
        delete currNode;
        currNode = nextNode;
    }
    m_size = 0;
}
template <typename T>
void RobotQueue<T>::enqueue(const T& x)
{
    Node<T> *newNode = new Node<T>;
    newNode->m_data = x;
    newNode->m_next = NULL;
    if(m_front == NULL)
        m_front = newNode;
    else
        m_back->m_next = newNode;
    m_back = newNode;
    m_size++;                           // Increments queue size
    return;
}
template <typename T>
void RobotQueue<T>::dequeue()
{
    Node<T>* tempNode = new Node<T>;
    if(m_front == NULL)
        cout << "dequeue error: Queue is empty" << endl;
    else
    {
        tempNode = m_front;
        m_front = m_front->m_next;
        delete tempNode;     <-- Segfault occurs here in RobotCustomer class
        m_size--;                       // Increments queue size
    }
    return;
}

我认为这与RobotCustomer是一个类有关,所以m_data不能指向它或其他什么?这里不是专家:p

RobotCustomer.h

/* ------------------  Class RobotCustomer ------------------ */
class RobotCustomer
{
private:
  string m_name;                // Name of Robot
  string* m_reqServices;        // Array of services requeseted
  int m_numServices;            // Number of services requested
  int m_currService;            // Number of services compelted
  bool m_busy;                  // Logic for if robot is in line/servicing
  bool m_done;                  // Logic for if robot is done
public:
  //- functions and such that I don't think affect the queue -//

感谢您抽出时间:)

---------------------使用构造函数/解构器更新------------------

机器人客户.cpp

// Default Constructor
RobotCustomer::RobotCustomer()
{
    m_name = "";
    m_numServices = 0;
    m_currService = 0;
    m_busy = false;
    m_done = false;
}
// Overloaded Constructor
RobotCustomer::RobotCustomer(string n, int x)
{
   m_name = n;
   m_numServices = x;
   m_reqServices = new string[m_numServices]; 
   m_currService = 0;
   m_busy = false;
   m_done = false;
}
// Default Destructor
RobotCustomer::~RobotCustomer()
{
    delete m_reqServices;
}

让我们看看函数中的几行:

Node<T>* tempNode = new Node<T>;
tempNode = m_front;
delete tempNode;

首先分配内存并将其指针分配给tempNode变量。然后重新分配该变量以指向其他内存,从而丢失原始指针。然后您尝试释放内存,该内存不再是您分配的原始内存。

这不应该导致崩溃(正如我所见),但这是内存泄漏。


我对导致崩溃的原因的猜测是,您可能在RobotCustomer构造函数中为m_reqServices成员动态分配内存。但是,如果您没有实现复制构造函数或复制赋值运算符,或者只是在这些函数中对指针进行浅层复制,那么使用赋值

newNode->m_data = x

enqueue函数中,您将有两个具有相同指针的对象,当其中一个对象被删除时,其析构函数会删除已分配的内存,而另一个对象指针现在指向未分配的内存。当您再次尝试释放它时,会导致未定义的行为

你需要阅读关于三、五和零的规则。我的建议是使用std::vectorstd::array(如适用),并简单地遵循零规则。

当然,谈到使用标准容器,我想知道为什么一开始不使用std::queue