2017-12-07 14 views
0

C++で二重リンクリストを作成していますが、コードを実行すると例外が発生します。例外は、例外がスローされました:書き込みアクセス違反です。 This-> headはnullptrでした。pop_frontおよびpop_back関数の修正方法を教えてください。

これは、このエラーが発生した後、プログラムがクラッシュするという意味で混乱します。

#include <iostream> 
#include "My_list.h" 

template<typename T> 
My_list<T>::My_list() 
{ 
    head = nullptr; 
    tail = nullptr; 
    size = 0; 
    empty = true; 
} 

template<typename T> 
My_list<T>::~My_list() 
{ 
    while (head) 
    { 
     My_node<T>* next_node = head->next; 
     delete head; 
     size--; 
     head = next_node; 
    } 
} 

template<typename T> 
My_list<T>::My_list(const My_list<T>& copy_list) 
{ 
    size = copy_list.size; 
    head = copy_list.head; 
    tail = copy_list.tail; 
    while (copy_list.head) 
    { 
     My_node<T>* next = copy_list->head->next; 
     head->next = copy_list->next; 
     size++; 
     head = next; 
    } 
} 

template<typename T> 
My_list<T>::My_list(const My_list&& new_list) 
{ 
    //add 
} 


template<typename T> 
void My_list<T>::push_front(T data) 
{ 
    My_node<T>* new_node = new My_node<T>(data); 
    new_node->next = nullptr; 
    new_node.previous = nullptr; 

    if (is_empty()) 
    { 
     head = new_node; 
     tail = head; 
     size++; 
     empty = false; 

    } 
    else 
    { 
     head->previous = new_node; 
     new_node->next = head; 
     head = new_node; 
     size++; 
     empty = false; 
    } 
} 

template<typename T> 
void My_list<T>::push_back(T data) 
{ 
    My_node<T>* new_node = new My_node<T>(data); 
    new_node->previous = nullptr; 
    new_node->next = nullptr; 

    if (is_empty()) 
    { 
     head = new_node; 
     tail = head; 
     size++; 
     empty = false; 
    } 
    else 
    { 
     tail->next = new_node; 
     new_node->previous = tail; 
     tail = new_node; 
     size++; 
     empty = false; 
    } 
} 
template<typename T> 
T My_list<T>::pop_front() 
{ 
    if (!is_empty()) 
    { 
     My_node<T>* temp = head; 
     head = head->next; 
     head->previous = nullptr; 
     size--; 
     return temp->get_data(); 
    } 
    else 
     cout << "The list is empty and cannot pop anything from it" << endl; 
} 

template<typename T> 
T My_list<T>::pop_back() 
{ 
    if (!is_empty()) 
    { 
     My_node<T>* temp = tail; 
     tail = tail->previous; 
     tail->next = nullptr; 
     size--; 
     return temp->get_data(); 
    } 
} 

template<typename T> 
T My_list<T>::front() 
{ 
    return head->get_data(); 
} 

template<typename T> 
T My_list<T>::back() 
{ 
    return tail->get_data(); 
} 


template <typename T> 
bool My_list<T>::is_empty() 
{ 
    if (empty) 
    { 
     return true; 
    } 
    else 
     return false; 
} 

メインファイル:

は、ここに私のコードです

#include <iostream> 
#include "My_list.h" 
#include "My_node.h" 
#include "My_node.cpp" 
#include "My_list.cpp" 
using namespace std; 

int main() 
{ 
    //list<int> list1; 

    //list1.push_back(12); 

    //cout << list1.front() << endl; 
    My_list<int> list; 
    list.push_back(22); 

    cout << list.front() << endl; 

    cout << "BEFORE POP" << endl; 
    cout << list.pop_front() << endl; 
    cout << "we did it!" << endl; 

    cin.get(); 
    return 0; 
} 

私はまだ固定にもらっていないコードと間違って他のものがあるかもしれません実現します。私はちょうど基本的なポップを取得したい、機能を押してプッシュし、次に他の問題を修正することができます。おそらく問題はコピーコンストラクタのような私の他の関数の1つにありますか?あなたが修正する価値があることに気がついたら、それは素晴らしいでしょう!

ありがとうございました。

答えて

2

pop_frontpop_back使用is_empty()決して更新empty。したがって、要素が追加されると、それらのメソッドはリストが空であるとは決して考えないので、ヌルポインタを逆参照します。

あなたは、リスト項目の除去後に空になり、そうであれば、trueemptyを設定するかどうかをチェックするpop_frontpop_backを変更する必要があります。

is_empty()headtailに変更して、リストが空であるかどうかを確認することもできます。この方法では、emptyメンバーを持つ必要がなくなります。

+1

「代替ソリューション」は間違いなくあります。冗長性の低い状態ほど、同期が外れる可能性は低くなります。 –

関連する問題