C ++我自己的堆栈类中的奇怪行为

时间:2015-03-28 12:06:45

标签: c++ class stack destructor

这是一个包含Stack类和其他函数的程序。

  • ReadTheFile() - 读取存储在num_file.txt中的数字,并返回带有这些数字的向量。
  • IntervalCheck() - 从输入向量中添加特定范围的数字,并返回仅包含这些数字的向量。
  • VecToMyStack() - 将数字从向量添加到堆栈。

    #include <iostream>
    #include <string>
    #include <vector>
    #include <fstream>
    #define STACK_EMPTY -1
    #define OUT_OF_STACK -2
    using namespace std;
    
    template <class T>
    class Stack {
    private:
        struct Node{
            T element;
            Node *prevElement;
        };
        size_t NumberOfElements;
        Node *tempAdr;
        Node *topElement;
        Node *newElement;
        Node *erasedElement;
    public:
        Stack(){
            topElement = new Node;
            topElement->prevElement = nullptr;
            NumberOfElements = 0;
        }
    
        ~Stack(){
            cout << endl << "I'm a destructor";
        while(NumberOfElements !=0 ){
            tempAdr = topElement->prevElement;
            delete topElement;
            topElement = tempAdr;
            NumberOfElements--;
        }
        delete topElement;
        }
    
        void push(T input_element){
            tempAdr = topElement;
            topElement = new Node;
            topElement->element = input_element;
            topElement->prevElement = tempAdr;
            NumberOfElements++;
        }
    
        void pop(){
            if (NumberOfElements == 0) throw STACK_EMPTY;
            else {
                tempAdr = topElement->prevElement;
                delete topElement;
                topElement = tempAdr;
                NumberOfElements--;
            }
        }
    
        T top(){
            return NumberOfElements != 0 ? topElement->element : throw STACK_EMPTY;
        }
    
        void insert(size_t position, T input_element){
            if (position >= NumberOfElements) throw OUT_OF_STACK;
            else {
                tempAdr = topElement;
                for (size_t i = 0; i < position; i++){
                    tempAdr = tempAdr->prevElement;
                }
                newElement = new Node;
                newElement->element = input_element;
                newElement->prevElement = tempAdr->prevElement;
                tempAdr->prevElement = newElement;
                NumberOfElements++;
            }
        }
    
        void erase(size_t position){
            if (position >= (NumberOfElements-1)) throw OUT_OF_STACK;
            else{
                tempAdr = topElement;
                for (size_t i = 0; i < position; i++){
                    tempAdr = tempAdr->prevElement;
                }
                erasedElement = tempAdr->prevElement;
                tempAdr->prevElement = tempAdr->prevElement->prevElement;
                delete erasedElement;
                NumberOfElements--;
            }
        }
    
        void print(){
            if (NumberOfElements != 0){
                tempAdr = topElement;
                for (size_t i = 0; i < NumberOfElements; i++){
                    cout << tempAdr->element << " ";
                    tempAdr = tempAdr->prevElement;
                }
            }
        }
    
        size_t size() { return NumberOfElements; }
    
    
    };
    
    
    vector<int> ReadTheFile() { 
        vector<int> vec_from_file;
        int buffer;
        ifstream basefile;
        basefile.open("num_file.txt", ios::in); 
        if (basefile.is_open()) {   
            do {
                if (basefile >> buffer) 
                    vec_from_file.push_back(buffer); 
                else { 
                    basefile.clear(); 
                    basefile.ignore(1, ' '); 
                }
            } while (!basefile.eof());  
            basefile.close();
        }
        else cout << "Unable to open file" << endl;
        return vec_from_file; 
    }
    
    
    vector<int> IntervalCheck(vector<int> vec_for_check){ 
        vector<int> out_vec;
        if (vec_for_check.empty()) cout << "There is nothing to check"; 
        else {
            int begin_int, end_int;
            do {
                cin.clear(); 
                cin.sync(); 
                cout << "Input the first and the last value of the interval: ";
                cin >> begin_int >> end_int;
            } while (cin.fail()); 
            for (auto &k : vec_for_check) 
                if (k > begin_int && k < end_int)
                    out_vec.push_back(k); 
        }
        return out_vec; 
    }
    
    
    Stack<int> VecToMyStack(vector<int> input_vec){
        Stack<int> output_st;
        if (input_vec.empty()) {
            cout << "the end";
        }
        else {
            for (auto &k : input_vec){
                output_st.push(k);
            }
        }
        return output_st;
    }
    
    int main(){
    
        int choice = 0;
        do {
            cin.clear();
            cin.sync();
            VecToMyStack(IntervalCheck(ReadTheFile())).print();
            cout << "Would you like to measure another interval? 1-yes 2-no";
            cin >> choice;
        } while (choice == 1);
        system("pause");
        return 0;
    }
    

整个程序应该将数字从文件推送到堆栈,并使用类的print()方法打印此堆栈。例如,如果有num_file.txt

  

0 1 2 3 4 5 6 7 8 9 10

在内部,该计划预计将以这种方式运作:

  • 输入间隔的第一个和最后一个值:0 10 / *零和 十个是由用户输入的* /
  • 1 2 3 4 5 6 7 8 9
  • 你想测量另一个间隔吗? 1-yes 2-no

但是当执行VecToMyStack(IntervalCheck(ReadTheFile())).print();行时,我正在

  

访问冲突读取位置0xFEEEFEEE。

异常。它似乎像我的Stack类的析构函数在print()函数之前运行。为什么会这样?我应该在Stack类或VecToMyStack()函数中添加一些特殊内容吗?

1 个答案:

答案 0 :(得分:0)

最后,经过几个小时的研究,我发现错过了代码的和平:

Stack(const Stack &object){
        tempAdr = object.topElement;
        T * tempMas=new T[object.NumberOfElements];
        for (size_t i = 0; i < object.NumberOfElements; i++){
            tempMas[i] = tempAdr->element;
            tempAdr = tempAdr->prevElement;
        }
        topElement = new Node;
        topElement->prevElement = nullptr;
        NumberOfElements = 0;
        for (int i = object.NumberOfElements - 1; i >= 0; i--){
            push(tempMas[i]);
        }
        delete[] tempMas;
    }

我知道没有重载赋值运算符,我的Stack类仍然不完整,但至少我的代码运行正常。