简体   繁体   中英

Implementation of stack using vectors in c++

#include<iostream>
#include<vector>
using namespace std;
class Stack {

private:
    int maxSize;
    vector<int> v;
    int top;
public:
    Stack(int size) {
        this->maxSize = size;
        this->v.reserve(this->maxSize);
        this->top = -1;
    }

    void push(int j) {
        if (!(this->isFull())) {
            this->v[++this->top] = j;
        } else {
            cout << "stack is full"<<endl;
        }

    }

    int pop() {
        if (!(this->isEmpty())) {

            return this->v[this->top--];
        } else {
            cout << "\nstack is empty"<<endl;
            cout<<  "StackOverflow "<<endl;
        }
    }

    int peak() {
        return this->v[this->top];
    }
    bool isEmpty() {
        return (this->top == -1);
    }

    bool isFull() {
        return (this->top == this->maxSize - 1);
    }

};

int main() {

    Stack s(10);

    s.push(10);
    s.push(20);
    cout<<s.pop();
    cout<<"\n"<<s.pop();
    s.push(40);
    cout<<"\n"<<s.pop();

}

How can I make this code more better and reliable for these reasons:

  • The output of this code is 20 10 40 .

  • But in the output I want to print "Stack is empty" after every time the stack is empty after popping out all the elements from the stack

  • It fails toprint "Stackis Empty " every time .

You have UB in your code:

this->v[++this->top] = j;

 return this->v[this->top--];    

ans so on. The fact that you reserved space in a std::vector does not make accessing thous elements legal, you access elements out of bounds. And you overcomplicated your code - std::vector maintains it's size so you do not need index top at all. All you need is push_back() adding element and use back() to access last and then pop_back() to remove it. You can use std::vector>::empty() or std::vector::size() to check if there are elements left.

The specific problem in your code is due to your attempting out of bounds access with a std::vector ; the behaviour of which is undefined . Note that reserve does not make that number of elements available for use; only potentially available without a subsequent memory reallocation. If you had used at rather than [] then your C++ standard library would have thrown a runtime error.

std::vector has push_back and a pop_back functions which does allow you to use it to model a stack reasonably effectively.

But , typedef std::stack<int> Stack; in place of all your code is by far the best way.

Don't use C++ standard library container objects to model other containers that are also in the C++ standard library. Container objects are really difficult to write properly; and take a lot of debugging.

The way you programmed it, it only prints "Stack is empty" if the stack is already empty when you call pop , not when it has 1 element and is only empty after calling pop .

Suppose you have 1 element on the stack. So top is 0.

int pop() {
    if (!(this->isEmpty())) {

This if evaluatetes to true, and therefore nothing will be printed. This is because isEmpty() evaluates to false with top set to 0.

What you want to do is doing the pop first, and then checking if the stack is empty. On top of checking it at the beginning either way, because you can't pop an empty stack.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM