2012-02-24 12 views
1

コピーコンストラクタ関数を呼び出すと、クラッシュするのはなぜですか?私のコピーコンストラクタで何が問題になっていますか?

私のクラス定義にあるコピー手順では、コピーを開始する前に他の元のキューのコピーとして作成されるキューが空であることを確認しています。つまり、キューq1が空ではないとしましょうq1をq2に変えたいと思います。私はあなたのコピーコンストラクタにbackfrontを初期化するのを忘れ

#include <iostream> 
#include <string> 
#include <cassert> 

using namespace std; 

class Dnode 
{ 
    public: 
     Dnode(int); 
     int n; 
     Dnode* l, *r; 
}; 

Dnode::Dnode(int tx) 
{ 
    n = tx; 
    l = r = NULL; 
} 

class Queue // reminder: insertions at the rear, deletions at the front 
{ 
    public: 
     Queue(); 
     void enqueue(int x); 
     int dequeue(void); 
     bool empty(void) const; 
     void display(void) const; 
     Queue(const Queue&); //copy constructor 

    private: 
     Dnode* front, *back; 
     void copy(Dnode*); 
     void free(); 

}; 

Queue::Queue() 
{ 
    front = back = NULL; 
} 


void Queue::enqueue(int x) 
{ 
    Dnode* d = new Dnode(x); 
    if (empty()) 
     front = back = d; 
    else 
    { 
     back->r = d; 
     d->l = back; 
     back = d; 
    } 
} 

int Queue::dequeue(void) 
{ 
    assert(! empty()); 
    Dnode* temp = front; 
    front = front->r; 
    if (front == NULL) 
     back = NULL; 
    else front->l = NULL; 
    int x = temp->n; 
    delete temp; 
    return x; 
} 


bool Queue::empty(void) const 
{ 
    return front == NULL; 
} 

void Queue::display(void) const 
{ 
    for (Dnode* d = front; d != NULL; d = d->r) 
     cout << d->n << " "; 
    cout << endl; 
} 

void Queue::copy(Dnode* dn) // "dn" will be "Front" of Queue being copied 
{       // this procedure will be called in Copy Constructor 
    Dnode* temp=front;  // found underneath this procedure 
    while(front!=back)  
    {      
     front=front->r; 
     delete temp; 
     temp=front; 
    } 

    delete temp; 

    front=back=temp=NULL; 

    if(dn!=NULL) 
    { 
     while(dn->r!=NULL) 
     { 
      enqueue(dn->n); 
      dn=dn->r; 
     } 
     enqueue(dn->n); 
    } 
} 

Queue::Queue(const Queue& x) 
{ 
    copy(x.front); 
} 

int main() 
{ 
    Queue q; 
    if (q.empty()) cout << "q empty" << endl; 

    for (int i = 0; i < 10; i++) q.enqueue(i); 

    q.display(); 

    int x = q.dequeue(); 

    cout << "x is " << x << endl; 

    q.display(); 

    Queue q1(q); //<----program crashes when we get here 

    q1.display(); 
} 
+1

コピーするとどうしてあなたが削除されますか?コピー中にメモリを解放する必要はありません。実際には、コピーを保持するためにQueueの新しいインスタンスにメモリを割り当てる必要があります。 – linuxuser27

+0

あなたはどこにでも初期化されていないポインタを使用して削除しています... – jrok

+0

あなたが言うように、他のキューがコピーになるキューを空にすることは不要かもしれませんが、それはプログラムが正しくクラッシュする理由であってはなりません。私は間違って何をしていますか? –

答えて

3

コピーコンストラクタと代入演算子を混同しています。代入演算子では、現在のキューを削除し、それを2番目のパラメータのコピーで置き換える必要があります。しかしこれはコピーコンストラクタです。現在のキューはありません。あなたのメンバーは初期化されていません。ですから、既存のキューを削除しようとすると、初期化されていないポインタがつぶれてしまいます。

+0

あなたはまったく時間でした:) –

2

.. Q1にQ2の内容をコピーする前に、Q1の内容を空にしたいです。

void Queue::copy(Dnode* dn) // "dn" will be "Front" of Queue being copied 
{ 
    Dnode* temp=front;  // found underneath this procedure 
    while(front!=back)  
    {      
     front=front->r; 
     delete temp; 
     temp=front; 
    } 

whileループは、その後、frontが初期化されない、とクラッシュを引き起こすように、ランダムに作用しています。

+0

コピープロシージャを呼び出すときに表と裏に値があると仮定していますが、これらが何であるかはわかりません。ところで、私はあなたが初期化されていないポインタについて大丈夫だと確信しています、それはちょうどそれがコピーコンストラクタになると何とかして混乱します... –

+0

@ user1073400 '新しい、それは未定義の振る舞いです。しかしそれはコピーコンストラクタでやっていることです。 – jrok

+0

@ user1073400:コピーメンバー機能は正常です。これは、 'Queue q1(q);'を呼び出すときに、あなたが作成したコンストラクタが初期化していないので、作成するオブジェクト 'q1'は' front'と 'back'のようなランダムな値を持ちます。順番に言えば、「正面」は(おそらく)ヌルではなく、背中とは異なるものです。 – qdii

0

フロントポインタとバックポインタをヌルに初期化し、ソースQueue xを各Dnodeをループして新しいキューにエンキューする必要があります。

+0

私の「新しい」キューは空ではなく、それをキューxのコピーに変えたいのですが? –

+0

コピーコンストラクタを使用していません。あなたが聞いたことを達成するためには、最初にQueueを使い切ってから、修正されたcopy()のフレーバーを呼び出す必要があります。 – Lou

+1

@ user1073400あなたの「新しい」キューには、どのようなものが含まれていますか?あなたのコピー*コンストラクタ*が実行されている間、オブジェクトはまだ完全には構築されていません。最初から新たに構築されています。おそらくあなたは代入演算子とコピーコンストラクタを混同しているでしょうか? – jrok

関連する問題