Why does this code crash while testing stack? - c++

OK, so I edited my code, but I still have two problems :
But here's my code first :
#include <iostream>
using namespace std;
struct stack
{
int data[5];
int top;
};
void push (int a, stack &S)
{
S.top++;
if (S.top<5)
{
S.data[S.top]=a;
}
else cout<<"Stack is full!!!"<<endl; S.top--;
}
int pop(stack &S)
{
if (S.top==-1)
{
cout<<"Stack is empty!"<<endl;
}
else
{
int temp=S.data[S.top];
S.data[S.top]=NULL;
S.top--;
return temp;
}
}
bool isEMPTY(stack &S)
{
if (S.top==-1)
return true;
else return false;
}
bool isFULL(stack &S)
{
if (S.top==5)
return true;
else return false;
}
int main()
{
stack S = { {}, -1 };
push(5,S); cout<<"5 is pushed \n"<<endl;
push(3,S); cout<<"3 is pushed \n"<<endl;
push(1,S); cout<<"1 is pushed \n"<<endl;
push(2,S); cout<<"2 is pushed \n"<<endl;
push(6,S); cout<<"6 is pushed \n"<<endl;
push(7,S); cout<<"7 is pushed \n"<<endl;
cout<<pop(S)<<"is popped\n"<<endl;
cout<<pop(S)<<"is popped\n"<<endl;
cout<<pop(S)<<"is popped\n"<<endl;
return 0;
}
So, the first problem is, when I pop I get a "Totally random value" and it's not like LIFO.
Second is, I actually intended on inserting 6 values, when I already had the max value = 5, so the output actually showed me the 6 values.

stack S;
Since stack is POD, the above line doesn't initialize the member top. As such, using an uninitialized top in push and pop functions invokes undefined behavior.
Write this:
stack S {}; //must be compiled in C++11 mode, else write : stack S = stack();
This value-initializes S and its members, which means, top is initialized to 0. The rest of the code may still have other problems, but at least you have fixed the issues with proper initialization. If you work with 0 as initial value of top, you've write the logic of push and pop accordingly!
Once you fix that, check the value of top before pushing and poping values from the stack, as the member array can have at most 5 elements, and you cannot pop more elements when it is empty. You must maintain these invariants.

I do not see where an object of type stack was created and how data member top was initialized.
Also take nto account that member function push does not check whether there is an attempt to add an item beyond the array.
You should define the object the following way
stack S = { {}, -1 };

else cout<<"Stack is full!!!"<<endl; S.top--;
is identical to :
else
{
cout<<"Stack is full!!!"<<endl;
}
S.top--;
as a general rule, try to avoid: writing if/else without curly brackets, and, avoid writing more then one line of code in the same line.

The mistake is:
stack s;//you define the local variable "s" without been intitialized.
push(5,s);//pass the uninlitialized "s" to the function "push",when debugging your code,"s.top" is not a expected "-1",but some value incredible~(often extreamly larger than 5),so your push operation failed!
stack S;
S.top = -1;
for(int i = 0; i < 5; i++)
{
S.data[i] = 0;
}

Related

Issues with a char stack implementation in c++?

I want to make a char stack implementation, but i think something is wrong with it because when i try to use it for my other function it does not word and library stack works. Can you help to find an issue:
using namespace std;
Stack::Stack(int size)
{
arr = new char[size];
capacity = size;
t = -1;
}
int Stack::size()
{
return (t + 1);
}
Stack::~Stack()
{
delete[] arr;
}
bool Stack::empty()
{
return size()==0;
}
void Stack::push(char x)
{
if (size()==capacity) {
cout<<"Push to full stack";
arr[++t]=x;
}
}
char Stack::pop()
{
if (empty()) {
cout<<"Pop from empty stack";
--t;
}
return 0;
}
char Stack::top()
{
if (!empty())
return arr[t];
else
cout<<"Top of the stack is empty";
return 0;
}
I want to make a char stack implementation, but i think something is wrong with it because when i try to use it for my other function it does not word and library stack works. Can you help to find an issue:
Thank you in advance!
I think you need to make some changes to the push and pop function for your Stack to work
In push, you should put arr[++t]=x; outside the if statement instead of inside as you want to add value to arr if the current size is less than its capacity instead of when it is equal
In pop, you should put arr[--t]; outside the if statement instead of inside as you want to remove and return the last value in the array if the stack is not empty. When it is empty, you should consider returning a default character such as the null terminator character \0. You should also want to use arr[t--] instead of arr[--t] as the last element is currently at t so you want it to evaluate arr[t] before decreasing its value (t--)
void Stack::push(char x)
{
if (size()==capacity) {
cout<<"Push to full stack";
return;
}
arr[++t]=x;
}
char Stack::pop()
{
if (empty()) {
cout<<"Pop from empty stack";
return '\0';
}
return arr[t--];
}

Member variable resetting back to 0

When running through the test the count variable from the class stack1 gets reset back to 0 when using its pop function. Strangely however, during the push loop, the count increases as intended but when pop occurs, the count gets reset back to 0 and subtracts into the negatives from there. Is there something I'm forgetting?
#include <iostream>
using namespace std;
class TheStack
{
public:
TheStack();
void push(int);
int pop();
bool isEmpty();
private:
const int MaxSize = 10;
int arr[10];
int count;
};
TheStack::TheStack()
{
count = 0;
}
void TheStack::push(int userInput)
{
if (count >= MaxSize)
{
cout << "Stack is full." << endl;
}
else
{
arr[count] = userInput;
count+=1;
}
}
int TheStack::pop()
{
if (isEmpty())
{
cout << "Stack is empty." << endl;
}
else
{
int temp = arr[count];
arr[count] = NULL;
count-=1;
return temp;
}
}
bool TheStack::isEmpty()
{
if (count == 0)
{
return true;
}
else
{
return false;
}
}
int main()
{
TheStack stack1;
if (stack1.isEmpty())
{
cout << "isEmpty() works" << endl;
}
stack1.pop();
for (int i = 0; i < 10; i++)
{
stack1.push(i);
}
stack1.push(0);
stack1.pop();
stack1.pop();
stack1.pop();
stack1.pop();
system("pause");
}
When you do push you first save the data into the array and then increment count. This means that in order to properly do pop you need to work in reverse: first decrement count and only then read data from the array.
But in the code you are doing it backwards. When the stack is full, count is at max value (10 in your case), and your arr[count] = NULL; writes beyond the array boundary. This causes undefined behavior and, in particular, destroys your count value. (This is why it suddenly becomes 0.)
Also:
arr[count] = NULL; makes no sense. NULL is supposed to be used in pointer contexts, not in integer contexts. This is not even guaranteed to compile.
What is the point of that anyway? Initially your array contains garbage above the current top of the stack. Why do you suddenly care to clean it up after doing pop?
Not all control paths of pop() return value. This is undefined behavior in itself.
const int MaxSize = 10; in the class definition is a C++11 feature. Since you are already using C++11, you can do the same for count. Just do int count = 0; right inside the class definition and you will not have to write the constructor explicitly.
Although in your implementation MaxSize would make more sense as a static const class member. In that case you'll also be able to declare your array as int arr[MaxSize];.
You must first decrease count and then access arr[count] in int TheStack::pop(). Now you get access above the last pushed element, event out of bound of array if the stack is full.

push object in the heap using pointer to the static container

class Node_Str{
public:
string name;
string value;
string type;
Node_Str(string name,string value,string type){
name=name;
value=value;
type=type;}};
static stack<Node_Str> s;
void find_token(string input){
int cursor=0;
string current="";
while(cursor<input.length()){
char value;
value=input[cursor];
cout<<value<<endl;
if(value=='('||value==')'||value=='+'||value=='-
'||value=='*'||value=='/'){
Node_Str* p=new Node_Str("pare",string(1,value),"Pare");
s.push(*p);
cursor++;
delete p;}
if(value==' '){
cursor++;
}
if(value=='1'||value=='2'||value=='3'||value=='4'){
Node_Str* p=new Node_Str("num",string(1,value),"Number");
s.push(*p);
cursor++;
delete p;}}}
int main(){
while(!s.empty()){
cout<<s.top().value<<" ";
s.pop(); }
return 0; }
The find_token function should separate the input string by white Space and constructing the Node_Str object with the value of that string. Then in the
main function, I would like to print it. The characters are limit. Just '1', '2','3','4','+,'-','*','/'.
Input is 4 + 4 , output should be 4+4. However, there is no output.
The comments already said about memory leak and forgetting to call find.
In addition to that, stack is a container in which to last to be pushed in would be the first to be popped out. In order to output 0 1 2 3, you would need to push in the stack in the sequence of 3 2 1 0.
Just giving a better version.
#include <iostream>
#include <stack>
using std::cout;
using std::stack;
static stack<int> s;
void find()
{
int* p;
for (int i = 3; i >= 0; i--) {
p = new int(i);
s.push(*p);
delete p; // p itself does not have to be returned so it can be safely deleted here
//This can also ne replaced by directly using s.push(i)
}
}
int main() {
find();
while (!s.empty())
{
cout << s.top() << " ";
s.pop();
}
return 0;
}
as suggested by leyanpan, data should be pushed into reverse order, to get the desired output. One more point is no need of dynamic allocation for int type. It is always better to store non array built in types in stack rather than heap.
Also allocating stack data structure as static variable will extend scope up to program termination. Better to use stack object as a local variable in main and pass it as are reference argument to function find.

The same expression but different result

So I am doing a question in leetcode. It is Implement Stack using Queues.
If I submit this code below. It is accepted.
class Stack {
public:
queue<int> que;
// Push element x onto stack.
void push(int x) {
que.push(x);
for(int i=0;i<que.size()-1;i++){
que.push(que.front());
que.pop();
}
}
// Removes the element on top of the stack.
void pop() {
que.pop();
}
// Get the top element.
int top() {
return que.front();
}
// Return whether the stack is empty.
bool empty() {
return que.empty();
}
};
but if I only change for(int i=0;i<que.size()-1;++i) to for(int i=0;i<=que.size()-2;i++), I got Time limitation exceeded. Last executed input: push(1),empty().Could somebody tell me why??? Thanks
queue::size() returns a size_t which is basically an unsigned number. and a negative unsigned number converts to a huge number.
So queue::size()-1 --> huge number (0xFFFFFFFF)

Implementation of stack in C++ without using <stack>

I want to make an implementation of stack, I found a working model on the internet, unfortunately it is based on the idea that I know the size of the stack I want to implement right away. What I want to do is be able to add segments to my stack as they are needed, because potential maximum amount of the slots required goes into 10s of thousands and from my understanding making the size set in stone (when all of it is not needed most of the time) is a huge waste of memory and loss of the execution speed of the program. I also do not want to use any complex prewritten functions in my implementation (the functions provided by STL or different libraries such as vector etc.) as I want to understand all of them more by trying to make them myself/with brief help.
struct variabl {
char *given_name;
double value;
};
variabl* variables[50000];
int c = 0;
int end_of_stack = 0;
class Stack
{
private:
int top, length;
char *z;
int index_struc = 0;
public:
Stack(int = 0);
~Stack();
char pop();
void push();
};
Stack::Stack(int size) /*
This is where the problem begins, I want to be able to allocate the size
dynamically.
*/
{
top = -1;
length = size;
z = new char[length];
}
void Stack::push()
{
++top;
z[top] = variables[index_struc]->value;
index_struc++;
}
char Stack::pop()
{
end_of_stack = 0;
if (z == 0 || top == -1)
{
end_of_stack = 1;
return NULL;
}
char top_stack = z[top];
top--;
length--;
return top_stack;
}
Stack::~Stack()
{
delete[] z;
}
I had somewhat of a idea, and tried doing
Stack stackk
//whenever I want to put another thing into stack
stackk.push = new char;
but then I didnt completely understand how will it work for my purpose, I don't think it will be fully accessible with the pop method etc because it will be a set of separate arrays/variables right? I want the implementation to remain reasonably simple so I can understand it.
Change your push function to take a parameter, rather than needing to reference variables.
To handle pushes, start with an initial length of your array z (and change z to a better variable name). When you are pushing a new value, check if the new value will mean that the size of your array is too small (by comparing length and top). If it will exceed the current size, allocate a bigger array and copy the values from z to the new array, free up z, and make z point to the new array.
Here you have a simple implementation without the need of reallocating arrays. It uses the auxiliary class Node, that holds a value, and a pointer to another Node (that is set to NULL to indicate the end of the stack).
main() tests the stack by reading commands of the form
p c: push c to the stack
g: print top of stack and pop
#include <cstdlib>
#include <iostream>
using namespace std;
class Node {
private:
char c;
Node *next;
public:
Node(char cc, Node *nnext){
c = cc;
next = nnext;
}
char getChar(){
return c;
}
Node *getNext(){
return next;
}
~Node(){}
};
class Stack {
private:
Node *start;
public:
Stack(){
start = NULL;
}
void push(char c){
start = new Node(c, start);
}
char pop(){
if(start == NULL){
//Handle error
cerr << "pop on empty stack" << endl;
exit(1);
}
else {
char r = (*start).getChar();
Node* newstart = (*start).getNext();
delete start;
start = newstart;
return r;
}
}
bool empty(){
return start == NULL;
}
};
int main(){
char c, k;
Stack st;
while(cin>>c){
switch(c){
case 'p':
cin >> k;
st.push(k);
break;
case 'g':
cout << st.pop()<<endl;
break;
}
}
return 0;
}