Недопустимый указатель отложенной очереди: ошибка при удалении класса

Функция dequeue моей шаблонной очереди отлично работает для очереди строк, но если я использую свой собственный класс 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 -//

Спасибо за ваше время 🙂

———————UPDATED_WITH CONSTRUCTORS / DECONSTRUCTORS ——————-

RobotCustomer.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;
}

0

Решение

Давайте посмотрим на несколько строк в вашей функции:

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

Сначала вы выделяете память и назначаете ее указатель на tempNode переменная. Затем вы переназначить эта переменная указывает на какую-то другую память, теряя оригинальный указатель. Затем вы пытаетесь освободить память, которая больше не является оригинальной памятью, которую вы выделили.

Это не должно вызывать сбой (насколько я могу видеть), но это утечка памяти.


мой Угадай что является причиной сбоя в том, что вы, вероятно, выделяете память динамически в RobotCustomer конструктор, для m_reqServices член. Но если вы не реализуете конструктор копирования или оператор копирования-присваивания или просто делаете мелкую копию указателя в этих функциях, то с присваиванием

newNode->m_data = x

в enqueue функция у вас будет два объект с тем же указателем, и когда один из них удаляется, его деструктор удаляет выделенную память, оставляя указатель других объектов, теперь указывающий на нераспределенную память, что приводит к неопределенное поведение когда вы попытаетесь освободить его снова.

Вам нужно прочитать о правила три, пять и ноль. Я рекомендую использовать std::vector или же std::array (в зависимости от обстоятельств) и просто следуйте правило нуля.

Конечно, говорить об использовании стандартные контейнеры заставляет меня задуматься, почему ты не используешь std::queue начать с?

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]