2017-12-07 1 views
0

C++에서 이중 연결 목록을 만들고 있는데 코드를 실행할 때 예외가 발생합니다. 예외는 Throw Exception : 쓰기 액세스 위반입니다. 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; 
} 

내가 아직 해결을 못 했어 코드를 잘못 다른 일이있을 수 있습니다 알고 있습니다. 난 그냥 기본 팝, 푸시 기능을 누른 다음 다른 문제를 해결할 수 얻을 싶어요. 아마도 문제는 복사 생성자와 같은 다른 기능 중 하나일까요? 고칠만한 가치가있는 것을 발견하면 그 것이 좋습니다!

감사합니다.

답변

2

pop_frontpop_back사용is_empty()하지만 결코 갱신empty. 따라서 요소가 추가되면 해당 메서드는 목록이 비어 있다고 생각하지 않으므로 null 포인터가 참조 해제됩니다.

당신은 목록 항목 제거 후 비어 있는지 확인하는 pop_frontpop_back을 수정해야하고, 만약 그렇다면, trueempty을 설정합니다.

is_empty()headtail으로 변경하여 목록이 비어 있는지 확인할 수 있습니다. 이렇게하면 empty 회원을 가질 필요가 없습니다.

+1

확실하게 "대체 솔루션"을 찾으십시오. 덜 중복 된 상태 일수록 더 적은 상태가 동기화되지 않을 수 있습니다. –