2016-04-06 27 views
0

Sıralı sıranın dequeue işlevim bir sıra dizisi için iyi çalışıyor, ancak özel Robot sınıfımı kullanırsam, işaretçiyi silmeye çalışırken çöküyor. Neden olduğunu merak ediyorum. Bilmiyorum ya bu gerekiyorsa (Templated Dequeue geçersiz işaretçi: Sınıf silme başarısız oluyor Sınıf

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

Benim şablonu kuyruk böyle yaklaşık görünür: 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; 
} 

dize kuyruğu çalışıyor ama bu hatayı alıyorum Örneğin

, Daha).

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

Ben m_data kendisine ya da bir şey işaret edemez böylece RobotCustomer bir sınıf olma ilgisi var varsayıyorum? Burada değil bir uzman: 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 -// 

teşekkürler zaman :)

için -------------------- -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

Bir yanıt MCVE yayınlamak istiyorsanız, çok fazla bilgi eksik – Slava

+0

nedir MCVE tam olarak nedir? Yapıcılar ve deconstructors? Google'a çok çabuk çalıştım ama hala emin değilim üzgünüm: p – Wezabi

+0

Bu bir [Minimal, Tam ve Doğrulanabilir Örnek] (http://stackoverflow.com/help/mcve). Bunu istemek, kurucuları, kopya yapıcıları ve yıkıcıları görmemiz gerektiği anlamına gelir. –

cevap

0

Fonksiyonunuzda hatlarının birkaç inceleyelim:

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

Önce belleği ayırır ve işaretçisini tempNode değişkenine atarsınız. Sonra , numaralı rotayı, bu değişkeni başka bir belleğe işaret ederek orijinal işaretçiyi kaybedecek şekilde yeniden atayabilirsiniz. Daha sonra belleğinizi boşaltmaya çalışın, ki artık ayırdığınız orijinal bellek değildir.

Bu, çarpmaya neden olmamalıdır (görebildiğim kadarıyla), ancak bir bellek sızıntısıdır. çökmesine neden olan sebep olarak


Benim tahminim muhtemelen m_reqServices üyesi için, RobotCustomer yapıcı dinamik bellek ayrılamadı olmasıdır. Eğer bir kopya-yapıcı veya kopya-atama operatörü uygulamak, ya da sadece enqueue işlevinde atama

newNode->m_data = x 

ile daha sonra, bu fonksiyonlarda ibrenin sığ bir kopyasını yapmazsak Ama iki olacak Aynı işaretçiye sahip nesnesi ve bunlardan biri silinirse, tahsis edilen bellek siler, serbest bırakılmaya çalıştığınızda, tanımsız davranış giden, diğer nesneleri işaretçisi artık ayrılmamış bellek işaret eden diğer nesneleri işaretçisi bırakarak.

the rules of three, five and zero hakkında okumanız gerekiyor. Benim önerim std::vector veya std::array (geçerli olduğu gibi) kullanmak ve the rule of zero'u takip etmektir.

Tabii ki, standard containers'u kullanma hakkında konuşmak, neden std::queue'u kullanmaya başlamadığınızı merak ediyor?

+0

Oh yea Farklı seçenekler ile uğraşırken, Node * tempNode = new Node ; - Düğüm * tempNode; – Wezabi

+0

Kullanıcıdan girdi aldığımda, 'm_reqServices = new string [m_numServices]; girişi doğruladıktan sonra. Sanırım bu test dosyasında bunu asla yapmam, m_reqServices boş. Yine de bir soruna neden olan "hiçbir kopya yapıcı veya atama operatörü" ile aynı fikirdeyim. std :: sıranın kullanılması hakkında Verdiğimiz bir ADT soyutQueue'dan türetilen kendi sıra sınıfını kullanmak zorunda olduğumuz bir ödev görevidir. – Wezabi

İlgili konular