基于数组的堆栈 - 析构函数中的错误

时间:2010-09-01 02:03:10

标签: c++ arrays stack adt

这是我对C ++的第一次可悲的尝试。我在C ++中做了一个基于数组的堆栈,析构函数抛出了一些内存转储。我无法弄清楚出了什么问题。



#include <stdio.h>
#include <iostream>
#include <exception>

using namespace std;

class FullStackException : public exception {
    virtual const char* what() const throw() {
        return "Stack is full.";
    }
} fsex;

class EmptyStackException : public exception {
    virtual const char* what() const throw() {
        return "Stack is empty.";
    }
} esex;

template <class D>
class ArrayBasedStack {
private:
    int t; //t represents top
    D *S;
    int arrSize;
public:
    ArrayBasedStack(int arraySize = 10);
    ~ArrayBasedStack();
    int size(); /*returns the number of elements stored*/
    void push(D&); /*inserts an element*/
    D pop(); /*removes and returns the last inserted element*/
    D top(); /*returns the last inserted element without removing it*/
    int isEmpty(); /*indicates whether no elements are stored*/
};

template <class D>
ArrayBasedStack<D>::ArrayBasedStack(int arraySize) {
    /* Elements are added from left to right */
    S = new D[arraySize];
    arrSize = arraySize;
    /* t keeps track of the index of the top element */
    t = -1;
}

template <class D>
ArrayBasedStack<D>::~ArrayBasedStack() {
    if(S != NULL) {
        int i = 0;
        for(i = 0; i < size(); i++) {
            S[i] = NULL;
        }
        cout << "about to delete S" << endl;
        delete[] S;
    }
}

template <class D>
int ArrayBasedStack<D>::size() {
    return t;
}

template <class D>
void ArrayBasedStack<D>::push(D& data) {
    if(t == arrSize) {
        throw fsex;
    } else {
        S[t] = data;
        t++;
    }
}

template <class D>
D ArrayBasedStack<D>::pop() {
    if(isEmpty()) {
        throw esex;
    }
    D element = S[t];
    S[t--] = NULL;
    return element;
}

/*
 * returns true if the stack is empty, false otherwise
 */
template <class D>
int ArrayBasedStack<D>::isEmpty() {
    return (t < 0);
}

int main(int argc, char *argv[]) {

    char inputs[][10] = {
        "str1"
    };

    char *i = NULL;

    ArrayBasedStack<char *> stack;
    i = inputs[0];
    stack.push(i);
    try {
        stack.pop();
    }
    catch(exception& ex) {
        cout << "ERR:" << ex.what() << endl;
    }
    return 0;
}


2 个答案:

答案 0 :(得分:2)

问题在于

    t = -1;

应该是

    t = 0;

因为当您添加第一个元素时,以下代码已被删除

    } else {
       S[t] = data;    // t == -1
       t++;
    }

答案 1 :(得分:0)

以下是罪魁祸首。

template <class D> 
void ArrayBasedStack<D>::push(D& data) { 
    if(t == arrSize) { 
        throw fsex; 
    } else { 
        S[t] = data;       // Should be S[++t] = data;
        t++;               // Comment out this line
    } 
} 

此实现假定't'指向堆栈中最顶层的元素而不是push的下一个可用位置

请注意,operator []和operator ++具有相同的优先级。由于它们从左到右关联,因此[]在operator ++之前进行评估。

在您的实施中,这是问题所在。将t初始化为-1时,将覆盖超出S [-1]的数组下标,从而导致undefined behavior

至少在我的系统上,当试图释放堆栈类的析构函数中的内存时问题浮出水面。这是一个典型的例子,在发生混乱之后,症状很明显可见

还建议push将参数设为D const &