2016-04-06 14 views
0

私のテンプレートキューのデキュー機能は文字列のキューで正常に機能しますが、私のカスタム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; 
} 

私はそれはM_DATAがそれか何かを指すことはできませんのでRobotCustomerがクラスであることに関係していると仮定していますか?ここではない専門家: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コンストラクタ/ 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

答えを出すには、MCVEを公開する必要があります。あまりにも多くの情報が欠落しています – Slava

+0

MCVEとは何ですか?コンストラクタとデコンストラクタ?私はそれをすばやくグーグルしようとしましたが、私はまだわかりません、申し訳ありません:p – Wezabi

+0

[最小、完全で、検証可能な例](http://stackoverflow.com/help/mcve)です。それを求めることは、コンストラクタ、コピーコンストラクタ、デストラクタを見る必要があることを意味します。 –

答えて

0

は、あなたの関数内の行の数を見てみましょう:

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

最初にメモリを割り当て、ポインタをtempNode変数に割り当てます。その後その変数を他のメモリを指すように再割り当てし、元のポインタを失います。次に、割り当てられた元のメモリではなくなったメモリを解放しようとします。

これはクラッシュ(私が見ることができるように)を引き起こしてはいけませんが、メモリリークです。クラッシュを引き起こしているものになど


マイ推測あなたはおそらくm_reqServicesメンバーのために、RobotCustomerコンストラクタ内で動的にメモリを割り当てることです。あなたはコピーコンストラクタまたはコピー代入演算子を実装する、あるいは単にenqueue機能が割り当て

newNode->m_data = x 

で、その後、これらの関数にポインタのシャローコピーをしない場合しかし、あなたは2を持っていますオブジェクトが同じポインタを持ち、そのうちの1つが削除されるとデストラクタによって割り当てられたメモリが削除され、他のオブジェクトポインタは割り当てられていないメモリを指し示し、は未定義の動作になります。

あなたは約the rules of three, five and zeroを読む必要があります。私の推奨は、std::vectorまたはstd::array(該当する場合)を使用し、単にthe rule of zeroに従うことです。

言うまでもなく、standard containersを使用して話をすると、なぜstd::queueを使用しないのでしょうか?

+0

オハイオ州オースティン私はさまざまなオプションを使いこなしていましたが、変更しようとしていました ノード * tempNode =新しいノード; 〜 ノード * tempNode; – Wezabi

+0

私はユーザーから入力を得ると、私は 'm_reqServices = new string [m_numServices];'という行を使います。入力を確認した後私はこのテストファイルでは、m_reqServicesは空ではありません。 私は「コピーコンストラクタまたは代入演算子がありません」と同意しますが、それでも問題は発生します。 std :: queueの使用については、与えられたADT abstractQueueから派生した独自のキュークラスを使用する必要がある宿題です。 – Wezabi

関連する問題