c++vectorstackfault

implementation of stacks using vector - segmentation fault in peek() function


#include <iostream>
#include <vector>

using namespace std;

class Stack{
  public:
  vector<string> vc;
  int length=0;

  void peek(){
     if(vc.size()==0){
         cout<< "The stack is empty"<<endl;
     }
     cout<< vc[length]<<endl; //----> does not work;
     //cout<<vc[vc.size()-1]; ---> does not work either
     //cout<<vc.end(); ----> does not work either;
  }

  void add(string value){
      vc.push_back(value);
      length++;
  }

  void pop(){
      vc.erase(vc.end());
      length--;
  }

  void show(){
    for (int i=0;i<vc.size();i++){
        cout << vc[i] << " ";
    }
    cout<<endl;
  }


};

int main()
{
    Stack mystack;
    mystack.peek();
    mystack.add("Hello");
    mystack.peek();
    mystack.add("frands");
    mystack.add("chai");
    mystack.add("pee");
    mystack.add("lo");
    mystack.show();
    mystack.peek();
    mystack.pop();
    mystack.show();
}

problem 1-> the problem arises in the peek() function i cannot access the last element in my vector space i get returned with a segmentation fault(core dump) error.

problem 2-> and while pasting this code on stack overflow i had to manually add 4spaces in each code line how to do this at one step (sorry for a silly question).


Solution

  • There are a few problems in your code:

      void peek(){
         if(vc.size()==0){
             cout<< "The stack is empty"<<endl;
         }
         cout<< vc[length]<<endl; //----> does not work;
      }
    

    If vc.size() == 0, you print out a message, and then proceed to index into the empty vector. You should return inside that if, to avoid looking at an invalid index.

    Below it you use use a length variable, which I presume is the acting the role of the vector's size(). EITHER you need to ensure the vector's size is the same as the stack's logical size (and then you don't need a length variable), OR you should be testing if length == 0, and not looking at size() here. Otherwise, you could have a positive size of vector, and a length of zero, and what's logically empty may print junk values.

    Another serious mistake, your pop function:

    void pop(){
        vc.erase(vc.end()); // <<< MISTAKE
        length--;
    }
    

    This is erasing the "end" element, which is not a valid position to erase. Remember, end denotes the first place after the last valid element in the vector, so your code yields undefined behavior. You should use the vector function pop_back instead, as it does precisely what you want. It also will reduce the size of the vector, meaning you don't need a length variable at all! Instead you can use the vector's size().

    Next, in peek():

    cout<< vc[length]<<endl;
    

    When a vector contains N things, they are indexed from 0..(N-1). Using the number of elements will go too far into the vector. Instead, use length-1 (or vc.size()-1 after fixing pop()). However, you can use vc.back() to access the last element without any need to compute its offset.