-6

的列表析構函數似乎工作,但與析構函數的元素和List_iter麻煩:類的析構函數,運行時錯誤:未處理的異常 - 堆棧溢出

未處理的異常:0xC00000FD:堆棧溢出(參數:00000001, 0x002E2F78)。

列表:

#ifndef GUARD_List_h 
#define GUARD_List_h 

#include "Element.h" 
#include "List_iter.h" 


template <typename T> 
class List { 

public: 
    List() : begins(new Element<T>), ends(new Element<T>), Element_count(0) { 

     begins->t_flag = 'b'; 
     ends->t_flag = 'e';  

     // double link: begins & ends 
     begins->next = ends; 
     ends->prev = begins;   
    } 
    virtual ~List() { 
     while (begins->next != ends) { 
      begins->prev = begins->next; 
      begins->next = begins->next->next; 
      delete begins->prev; 
     } 
     delete begins; 
     delete ends; 
    } 

    typedef List_iter<T> iterator; 

    iterator begin(void) const { 

     iterator it(begins); 
     return it; 
    } 
    iterator end(void) const { 

     iterator it(ends); 
     return it; 
    } 

    void push_back(const T val) { 

     Element<T>* elem = new Element<T>;  // create: new-elem   
     elem->data = val;      // set data 

     elem->prev = ends->prev;    // link: new-elem to last-data-elem 
     ends->prev->next = elem;    // link: last-data-elem to new-Element        

     elem->next = ends;      // link: new-elem to List-end    
     ends->prev = elem;      // link: List-end to new-elem 

     Element_count++;      // update: when List grows  
    } 
    T at(const size_t pos) const { 

     return get_Element(pos)->data; 
    } 
    void del(const size_t pos) const { 

     Element<T>* elem = get_Element(pos); // get: Element for deletion   

     elem->prev->next = elem->next;   // rejoin: double link 
     elem->next->prev = elem->prev;   // rejoin: double link 

     delete elem; 

     Element_count--;      // update: when List shrinks 

    } 
    void clear(void) { 

     Element<T>* ep = begins->next; 
     Element<T>* ep_next = ep->next; 

     while (ep->t_flag != 'e'){ 

      delete ep; 
      ep = ep_next; 
      ep_next = ep->next; 
     } 

     begins->next = ends; 
     ends->prev = begins; 

     //begins->data = 0r; 
     //ends->elem_ID = 0; 

     Element_count = 0; 

    } 

    size_t size(void) const { 
     return Element_count; 
    } 
    bool empty(void) const { 

     if (Element_count == 0){ return true; } 
     else { return false; } 
    } 


private: 
    Element<T>* begins;       // List begins 
    Element<T>* ends;        // List ends 
    size_t Element_count;       // List size 

    Element<T>* get_Element(const size_t pos) const  { 

     if (empty())      { 
      std::cerr << "No Element - Empty List"; 
      throw; 
     } 
     if (pos < 0 || pos >= Element_count){ 
      std::cerr << "No Element - Out of Range"; 
      throw; 
     } 

     iterator it; 

     // Determine the more efficent iteration direction(forward or reverse) ? 
     if ((Element_count/2) > pos) { 

      it = begin(); 
      for (size_t i = 0; i <= pos; i++){ 
       it++; 
      } 

     } 
     else { 

      it = end(); 
      for (size_t i = size() - pos; i > 0; i--){ 
       it--; 
      } 
     } 

     return it.elem; 
    } 

}; 
#endif 

元素:

#ifndef GUARD_Element_h 
#define GUARD_Element_h 

template <class T> 
class List; 

template <class T> 
class List_iter; 


template <class T> 
class Element { 

public: 
    Element() : prev(nullptr), next(nullptr), data(), t_flag(' ') {} 
    virtual ~Element() { 
     delete prev; 
     delete next;   
    } 
    friend List<T>; 
    friend List_iter<T>; 

private: 
    Element<T> *prev; 
    Element<T> *next; 

    T data; 
    int elem_ID; 
    char t_flag; 
}; 
#endif 

List_iter:

#ifndef GUARD_List_iter_h 
#define GUARD_List_iter_h 

template <class T> 
class List; 


template <class T> 
class List_iter { 

public: 
    List_iter(Element<T>* e = nullptr) : elem(e) {} 
    virtual ~List_iter() { 
     delete elem; 
    } 
    friend List<T>; 

    T operator*(void){ 

     if (elem->t_flag == 'e'){ 

      elem = elem->prev; 
     } 
     else if (elem->t_flag == 'b'){ 

      elem = elem->next; 
     } 
     return elem->data; 
    } 

    Element<T>* operator++(void) { 

     if (elem->next->t_flag == 'e'){ 
      return nullptr; 
     } 

     elem = elem->next; 
     return elem; 
    } 
    Element<T>* operator--(void) { 

     if (elem->prev->t_flag == 'b'){ 
      return nullptr; 
     } 

     elem = elem->prev; 
     return elem; 

    } 
    List_iter operator+(const int val) { 

     for (int i = 0; i < val; i++){ 

      this->elem = this->elem->next; 
     } 
     return *this; 
    } 
    List_iter operator-(const int val) { 

     for (int i = 0; i < val; i++){ 

      this->elem = this->elem->prev; 
     } 
     return *this; 
    } 

    bool operator!=(const List_iter& rhs) const { 

     return rhs.elem != elem; 
    } 
    bool operator>(const List_iter& rhs) const { 

     return (this->elem->elem_ID > rhs.elem->elem_ID); 
    } 
    bool operator<(const List_iter& rhs) const { 

     return (this->elem->elem_ID < rhs.elem->elem_ID); 
    } 
    bool operator>=(const List_iter& rhs) const { 

     return (this->elem->elem_ID >= rhs.elem->elem_ID); 
    } 
    bool operator<=(const List_iter& rhs) const { 

     return (this->elem->elem_ID <= rhs.elem->elem_ID); 
    } 


private: 
    Element<T>* elem; 

}; 
#endif 

主:

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


int main() { 

    List<int> ls; 
    List<int>::iterator begin = ls.begin(); 
    List<int>::iterator end = ls.end(); 
    List<int>::iterator iter = begin; 

    std::cout << "Attempt to retrieve data from empty list: ls.at(3)" << std::endl; 
    std::cout << "--------------------------------------------------" << std::endl; 
    //std::cout << ls.at(3) << std::endl << std::endl; 

    std::cout << "Test: growing list does not invalidate iter" << std::endl; 
    std::cout << "-------------------------------------------" << std::endl; 
    std::cout << "Empty list" << std::endl << std::endl; 

    std::cout << "begin addr: " << &begin << " " << std::endl; 
    std::cout << "end addr: " << &end << " " << std::endl; 


    std::cout << std::endl << "Add data to list: 33 " << std::endl << std::endl; 
    ls.push_back(33); 

    std::cout << "begin addr: " << &begin << " " << std::endl; 
    std::cout << "end addr: " << &end << " " << std::endl; 

    std::cout << std::endl << "Add data to list: 856 " << std::endl << std::endl; 
    ls.push_back(856); 

    std::cout << "begin addr: " << &begin << " " << std::endl; 
    std::cout << "end addr: " << &end << " " << std::endl; 
    std::cout << "clear() " << std::endl << std::endl; 



    ls.clear(); 



    std::cout << std::endl << std::endl; 
    std::cout << "Add data to list: 0 1 2 3 4 5 6 7 8 9" << std::endl; 
    std::cout << "-------------------------------------------------" << std::endl; 
    for (int i = 0; i != 10; i++){ 
     ls.push_back(i); 
    } 


    std::cout << std::endl << std::endl; 
    std::cout << "[email protected] begin+4" << std::endl; 
    std::cout << "-------------" << std::endl; 
    std::cout << *(iter + 4) << std::endl; 

    std::cout << std::endl << std::endl; 
    std::cout << "[email protected] begin->end" << std::endl; 
    std::cout << "----------------" << std::endl; 
    iter = begin; 
    while (iter++){ 

     std::cout << *iter << " "; 
    } 


    std::cout << std::endl << std::endl << std::endl; 
    std::cout << "[email protected] end->begin" << std::endl; 
    std::cout << "----------------" << std::endl; 
    iter = end; 
    while (iter--){ 

     std::cout << *iter << " "; 
    } 




    std::cout << std::endl << std::endl << std::endl; 
    std::cout << "for/iter: begin->end" << std::endl; 
    std::cout << "----------------" << std::endl; 
    for (iter = begin; iter++;){ 

     std::cout << *iter << " "; 
    } 


    std::cout << std::endl << std::endl << std::endl; 
    std::cout << "iter arith: +4 +1 -1" << std::endl; 
    std::cout << "--------------------" << std::endl; 
    iter = ls.begin(); 
    iter = iter + 4; 
    std::cout << *iter << " "; 
    std::cout << *(iter + 1) << " "; 
    std::cout << *(iter - 1) << " "; 



    std::cout << std::endl << std::endl << std::endl; 
    std::cout << "[email protected]: (0)(1)(2)(3)(4)(5)(6)(7)(8)(9)" << std::endl; 
    std::cout << "-------------------------------------" << std::endl; 
    for (int i = 0; i != 10; i++){ 

     std::cout << ls.at(i) << " "; 

    } 



    //ls.clear(); 


    List<std::string> ls_str; 
    ls_str.push_back("Hello"); 
    ls_str.push_back("World"); 



    return 0; // breakpoint 
} 

enter image description here

+0

這裏有一大堆代碼。建議您使用調試器來隔離您的問題。 – Chad

+0

大聲笑,呻吟,如果你不張貼代碼呻吟,如果你這樣做。 我已經使用調試器來隔離我的問題析構函數(你讀過OP)..觸發主要的第二行。 – tuk

+0

這裏沒有證據表明堆棧溢出,只是訪問衝突。 – aschepler

回答

0

新元素調用,因此擁有List,所以只有List可以刪除Element。 List_iter不需要析構函數,因爲它只包含一個指針。