类析构函数,运行时错误:未处理的异常 - 堆栈溢出

时间:2015-04-24 14:21:43

标签: c++ runtime-error stack-overflow destructor unhandled-exception

List的析构函数似乎可以工作,但是对于Element和List_iter的析构函数有问题:

未处理的异常:0xC00000FD:堆栈溢出(参数:0x00000001,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 << "data@ begin+4" << std::endl;
    std::cout << "-------------" << std::endl;
    std::cout << *(iter + 4) << std::endl;

    std::cout << std::endl << std::endl;
    std::cout << "data@ 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 << "data@ 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 << "data@: (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

1 个答案:

答案 0 :(得分:0)

新元素调用,因此由List拥有,因此只有List才能删除Element。 List_iter不需要析构函数,因为它只包含一个指针。