Why does my stack object change a default value after being created? - c++

So I have a stack created as below. The variable top is supposed to represent the current index, or the "top index". So by doing some testing, the constructor does get called and the value of top is -1 while the program is still running the constructor method. However, after creating the stack object, and testing to see what the value of top is, I keep getting top to be 32767. Literally, all that main does is create a new stack as
Stack s; //Testing while this is running to see value of top... I get -1
//Testing here to see value of top... I get 32767
-
The stack is created as shown below.
#ifndef __STACK_H_
#define __STACK_H_
class Stack{
int stackSize;
int top;
char* items;
public:
Stack();
~Stack();
void push(char c);
char pop();
bool isFull();
bool isEmpty();
};
#endif
And the implementation as below:
/* STACK IMPLEMENTATION FILE */
#include "stack.h"
#include <iostream>
using namespace std;
Stack::Stack(){
cout << "Ctor is run." << endl;
stackSize = 10; //Stack Size is 10
int top = -1; //Currently empty stack
cout << top << endl;
items = new char[stackSize];
}
Stack::~Stack(){ //Destructor
delete[] items;
}
void Stack::push(char c){ //Push next into stack
items[++top] = c;
cout << top << endl;
}
char Stack::pop(){ //Pop one from stack
return items[top--];
}
bool Stack::isFull(){ //Checks to see if stack is full
if (top + 1 == stackSize) return true;
}
bool Stack::isEmpty(){ //Checks to see if stack is empty
if (top == -1) return true;
}

You want top = 1 not int top = 1 in your constructor. The former assigns to the member, the latter initialises a local variable that goes out of scope at the end of the constructor.

Related

C++ Stacks with Array Implementation for Values of type double

So I'm trying to figure out how to make a Stack class with array implementation using values of the type double.
Heres the full header file...
#ifndef STACK_H
#define STACK_H
class Stack
{
private:
double *stackArray; //Pointer to the Stack array.
int stackSize; //The size of stack.
int top; //The first "plate" on top of the stack.
void copy(const Stack &copy); //Copy Constructor
void destroy(); //The fxn the destructor calls.
public:
Stack(int); //Constructor
/*
Stack(const Stack&); //Copy Constructor
*/
~Stack(); //Destructor
//STACK OPERATIONS:
void push(double); //Adds a node on top of the stack.
void pop(double &); //Removes node on top of stack.
bool isEmpty() const; //Returns true if stack is empty, false otherwise.
bool isFull() const; //Returns true if stack is full, false otherwise.
double peek(); //Gets the top item of the stack without removing the item.
int getSize(); //Makes the array larger if the capacity of the array is being reached.
};
#endif
And here's the full implementation file...
#include "Stack.h"
#include <iostream>
using namespace std;
Stack::Stack(int size) //The Constructor
{
stackArray = new Stack[size]; //Dynamically allocate memory for an array of a stack variable.
stackSize = size;
top = -1; //Set the top of the stack to -1. So its empty.
}
Stack::~Stack() //The destructor
{
destroy(); //Calls the destroy function to delete the array.
}
void Stack::push(double value) //Adds a new 'plate' on the stack
{
if (isFull())
{
cout << "The stack is full.\n"; //Prints out a message saying the stack is already full
}
else //Otherwise...
{
top++; //Increment top....
stackArray[top] = value; //...So we can make 'value' the new top in the array.
}
}
void Stack::pop(double &value) //Removes a 'plate' from the stack
{
if (isEmpty())
{
cout << "The stack is empty.\n";
}
else //Otherwise...
{
value = stackArray[top]; //Make 'value' the current top.
top--; //Removes the current value of top from the stack.
}
}
bool Stack::isEmpty() const
{
bool status; //Tells the current status of the stack
if (top == -1) //If theres nothing in the stack...
{
status = true; //...status returns true.
}
else //Otherwise...
{
status = false; //...The stack MUST have something already in it.
}
return status;
}
bool Stack::isFull() const
{
bool status;
if (top == stackSize - 1) //Checks if the top of the stack is equal to the max stack size entered.
status = true; //Returns true if stack is full.
else
status = false; //Or false if not.
return status;
}
void Stack::destroy()
{
delete [] stackArray; //Delete the Stack Array.
}
double Stack::peek() //Gets the top item of the stack without removing item
{
return stackArray[top];
}
int Stack::getSize() //Determines the size of the stack
{
int numItems = 0; //Variable to store number of items in stack.
for (int index = 0; index < stackSize; index++) //Goes through all the items in the stack....
{
numItems++; //...and counts them.
}
return numItems;
}
/****
void copy(const Stack &copy) //Deletes memory associated with stack
{
}
***/
The driver Looks like this....
#include <iostream>
#include "Stack.h"
using namespace std;
int main()
{
int stackSize;
Stack stack1(10);
cout << "Lets get the stack size!\n";
cout << stack1.getSize();
return 0;
}
My issue is that when I try to run this, It gives me the following error:
Stack.cpp: In constructor ‘Stack::Stack(int)’:
Stack.cpp:13:32: error: no matching function for call to ‘Stack::Stack()’
stackArray = new Stack[size]; //Dynamically allocate memory for an array of a stack variable.
^
In file included from Stack.cpp:6:0:
Stack.h:20:9: note: candidate: Stack::Stack(int)
Stack(int); //Constructor
^~~~~
Stack.h:20:9: note: candidate expects 1 argument, 0 provided
Stack.h:9:7: note: candidate: constexpr Stack::Stack(const Stack&)
class Stack
^~~~~
Stack.h:9:7: note: candidate expects 1 argument, 0 provided
Stack.cpp:13:32: error: cannot convert ‘Stack*’ to ‘double*’ in assignment
stackArray = new Stack[size]; //Dynamically allocate memory for an array of a stack variable.
Im not exactly sure what is going on here, if anyone can help me out that would be really great.
Also can someone give me a few tips on how should I approach the copy constructor and overloaded assignment operator for this class? Im not very good with those and am not sure how they would fit into this class implemenation.
This is the constructor u r trying to call
Stack::Stack(int size) //The Constructor
{
stackArray = new Stack[size]; //Dynamically allocate memory for an array of a stack variable.
stackSize = size;
top = -1; //Set the top of the stack to -1. So its empty.
}
Now, note that in the constructor you are allocating a dynamic array of Stacks and of size size.
Here stackArray = new Stack[size]
You have two problems
The allocation uses the default constructor for the stack and you don't have one because you declared a custom one.
If you use the custom constructor, you will have an infinite recursion.
You have to provide the right type of elements of the array that will be allocated (which, from the rest of the code, seems to be double) instead of Stack type to be
stackArray = new double[size].

Pop and push in stacks

I have a Data Structures assignment to use stacks for postfix algorithm. I think I'm nearly there but am struggling on a couple of things.
What do I put into the postfixstack.pop() arguments on Line 83 of cpp file?
How do I check if the stack is empty on Line 87 of cpp file?
I have 2 files, a .cpp and a .h file, both of them are below.
Thanks for any help.
using namespace std;
#include <iostream>
#include <stdlib.h>
#include <string>
#include "stack.h"
//Purpose of the program: **
//Algorithm: **
int main()
{
stack postfixstack; // integer stack
string expression; // user entered expression
cout << "type a postfix expression: " ;
cin >> expression;
int i = 0; // character position within expression
char item; // one char out of the expression
int box1; // receive things from pop
int box2; // receive things from pop
while (expression[i] != '\0')
{
try
{
item = expression[i]; // current char
// ** do all the steps in the algorithm given in Notes-1
if (item >= '0' && item <= '9') {
postfixstack.push(item);
}
else if (item == '+' || item == '-' || item == '*') {
if (item == '+') {
postfixstack.pop(box1);
postfixstack.pop(box2);
int tempResult = (box1 + box2);
postfixstack.push(tempResult);
}
if (item == '-') {
postfixstack.pop(box1);
postfixstack.pop(box2);
int tempResult = (box1 - box2);
postfixstack.push(tempResult);
}
if (item == '*') {
postfixstack.pop(box1);
postfixstack.pop(box2);
int tempResult = (box1 * box2);
postfixstack.push(tempResult);
}
}
else {
throw ;
}
} // this closes try
// Catch exceptions and report problems and quit the program now (exit(1)).
// Error messages describe what is wrong with the expression.
catch (stack::Overflow) {
{cerr << "Error: You have caused the stack to overflow." << endl; }
exit(1);
}
catch (stack::Underflow)
{cerr << "Error: You have caused the stack to underflow." << endl;
exit(1);
}
catch (char const* errormsg ) // for invalid item case
{cerr << "Error: You have entered an invalid item." << endl;
exit(1);
}
i++; // go back to the loop after incrementing i
}// end of while
// After the loop successfully completes:
// Pop the result and show it.
*postfixstack.pop();*
// If anything is left on the stack, an incomplete expression
// was found so inform the user.
if (*Need to check if stack is empty*) {
cerr << "Elements remain on the stack, incomplete expression error" << endl;
exit(1);
}
}// end of the program
****This is the beginning of the header file*****
// File type: header file stack.h
//=======================================================
//----- Globally setting up the aliases ----------------
const int MAX = 10; // The MAX number of elements for the stack
// MAX is unknown to the client
typedef int el_t; // the el_t type is char for now
// el_t is unknown to the client
//-------------------------------------------------------
class stack
{
private: // to be hidden from the client
el_t el[MAX]; // el is an array of el_t's
int top; // top is index to the top of stack
public: // available to the client
// Add exception handling classes here
class Overflow {}; // empty class – used as an exception name only
class Underflow {}; // empty class – used as an exception name only
// prototypes to be used by the client
// Note that no parameter variables are given
stack(); // constructor to create an object
~stack(); // destructor to destroy an object
// PURPOSE: if not full, enters an element at the top;
// otherwise throws an exception - Overflow
// PARAMETER: pass the element to be pushed
void push(el_t);
// PURPOSE: if not empty, removes and gives back the top element;
// otherwise throws an exception - Underflow
// PARAMETER: provide variable to receive the popped element (by ref)
void pop(el_t&);
// PURPOSE: if not empty, gives the top element without removing it;
// otherwise, throws an exception - Underflow
// PARAMETER: provide the top element of the stack (pass by reference)
void topElem(el_t&);
//PURPOSE: Determines if the stack is Empty. Returns true if stack is empty
bool isEmpty();
//PURPOSE: Determines if the stack is Full. Returns true if stack is full
bool isFull();
//PURPOSE: Displays all of the elements of the stack
void displayAll();
//PURPOSE: Clears all of the elements in the stack until it is empty
void clearIt();
};
The way you are implementing the stack as an array you can use the index (your top variable) to keep track of your stack's size as long as its use is well defined.
For instance, you can say that top is pointing to the next available place to put a new element so that an empty stack would have top == 0. This would solve the part for checking if an array is empty.
Following that same definition when you pop the stack you're removing the top element. If the datatype your stack is holding is a simple type you can just decrease the value of top by one.
void pop (el_t& val) //Perhaps return the value instead of return by reference
{
val= el[--top]; //Decrease top first because top is pointing to next EMPTY space.
}

error C4700: uninitialized local variable 'c' used ,

Can anyone explain this error and typedef char with array and the best scenario to implement the stack with array?
typedef char StackItemType;
class stack {
public:
stack(int size)
{
items = new StackItemType[size];
maxstack = size;
top = -1;
}
~stack() {
delete[] items;
}
bool isEmpty();
bool isFull();
bool push(char newitem);
bool pop(char *stacktop);
private:
StackItemType *items;
int top, maxstack;
};
int main()
{
StackItemType c ;
stack stack(5);
stack.push('a');
stack.push('b');
stack.push('c');
cout << c;
cout << endl;
system("pause");
}
In your code your declare a variable c. Then the first thing you try to do with the variable is print it's value. But you have never given it a value so the compiler gives you an 'uninitialised local variable' error. That's what it means, you are trying to use the value of a variable before you have given the variable a value.
I'm guessing that you meant to give c the value of the top item on the stack. If so then you should have written this code
StackItemType c ;
stack stack(5);
stack.push('a');
stack.push('b');
stack.push('c');
stack.pop(&c); // <<--- new code here that gives c a value
cout << c;
cout << endl;
system("pause");

Template Stack and LIFO C++

So I'm trying to learn about Templates and the Fifo and Lifo stack stuff. I've been playing around with some code that deals with this, and I can get the int data to do what I want for testing but I can't for the life of me figure out how to get this to work with a string.
The way I have the code keeps crashing on me, but doesn't give me any errors, so I thought I'd pop in here and see if anybody could tell me what I'm doing wrong. Here's my code:
-----------//my header//---------------------
#include <stdlib.h>
#include <iostream>
#include <string>
#ifndef STACK_H_
#define STACK_H_
template<class T>
class StackTest
{
private:
unsigned int maxSize;
T *stackData;
int top;
public:
StackTest(int size){
stackData = new T[size];//to hold the T ‌type data items
top = -1;//no items on the stack
maxSize = size;//set maximum size that stack can hold
}
virtual ~StackTest(){}
int count(){
return top + 1;
}
bool isEmpty(){
return top == -1 ? true : false;
}
bool isFull(){
return top == maxSize - 1 ? true : false;
}
T* peek(){
if(!isEmpty())//check for empty
return &stackData[top - 1];
}
T* pop(){
if(!isEmpty()){
top -= 1;//decrease the top by 1 to indicate the delete
return &stackData[top];//return deleted item
}
return NULL;
}
void push(T* item){
stackData[top++] = *item;//insert to data array and increase the top by one
}
};
#endif /* STACK_H_ */
-----------//my main//---------------
#include <iostream>
#include <string>
#include "Pair.h"
using namespace std;
int main() {
int dataTest;
string strTest;
StackTest<int> intStack(10);
StackTest<string> stringStack(50);
//Insert data into the stack
dataTest = 3;
intStack.push(&dataTest);
dataTest = 4;
intStack.push(&dataTest);
dataTest = 5;
intStack.push(&dataTest);
dataTest = 6;
intStack.push(&dataTest);
strTest = "test";
stringStack.push(&strTest);
//Show the top item
cout << *intStack.peek() << endl;
cout << *stringStack.peek() << endl;
//Pull the top item out (twice)
intStack.pop();
intStack.pop();
//Show the new top item
cout << *intStack.peek() << endl;
return 0;
}
So if anyone feels like giving me some pointers I would really appreciate it, thanks.
There are a few issues with your implementation. One of the most subtle is in the push() member function:
void push(T* item){
stackData[top++] = *item; //insert to data array and increase the top by one
// ^^
// You want pre-increment here!
}
This is incrementing top and using the old value as an index into stackData. Since top is -1 when the stack is empty, your program is actually doing:
stackData[-1] = *item;
top = 0;
Needless to say that the first assignment results in undefined behavior.
Another source of undefined behavior is the peek() member function, which does not return anything when the stack is empty:
T* peek(){
if(!isEmpty())//check for empty
return &stackData[top - 1];
}
Per paragraph 6.6.3/2 of the C++11 Standard:
[...] Flowing off the end of a function is equivalent to a return with no value; this results in undefined
behavior in a value-returning function.
But that's not the only issue: the other problem is with the access of stackData:
return &stackData[top - 1];
When top is not equal to or greater than one, this will also result in undefined behavior, since you would be taking the address of a (non-)object located at a negative address in the array.
Also, I suggest to rewrite isEmpty() and isFull() as follows:
bool isEmpty(){
return (top == -1);
}
bool isFull(){
return (top == maxSize - 1);
}
As a general advice, consider not using the value -1 for top when the stack is empty. As Ben Voigt mentions in the comments, this is leading you to a lot of off-by-one errors.
Also, as pointed out by DyP, your destructor is not freeing the memory allocated in the constructor, so your StackTest object is leaking memory. And after doing that, since we're at it, you may want to have a look at the so-called Rule of Three, that your program would be violating.

C++ HW Help using stack

I am a little stuck on how to use the stack and why I would even use stack in the code I am writing. The assingment says to write a program that checks if the user input is well-Iformed or not. It is a simple prgram that has three different selections the use can choose from. 1. basic brackets () 2. standard brackets ()[]{} and 3. User-definded brackets. The only thing the main program is suppose to do is to check if the users input is well-formed or not and display only that message on the screen.
I have a StackLS.cpp and a Stack.h file I am using along with my main.cpp. I will paste a sample code below from each.
StackLS.h
typedef int elemType; // flexible data type
class StackLS
{
private:
// inner class node
class Node
{
public:
elemType data; // data portion
Node *next; // link to the seccessor
}; // end Node
// data members
Node *topItem; // pointer to the top element of this stack
// utilities
public:
// constructors
StackLS(void); // default constructor
StackLS(const StackLS& aStack); // copy constructor
// observers
bool isEmpty(void) const;
// returns true if this stack is empty
// false otherwise
bool isFull(void) const;
// returns true if this stack is full
// false otherwise
elemType top(void) const;
// precondition: this stack is not empty
// returns top element in this stack
// transformers
void push(const elemType& item);
// precondition: this stack is not full
// adds item to this stack
void pop(void);
// removes top element from this stack if exist
// remains empty otherwise
void makeEmpty(void);
// makes this stack empty
// destructor
~StackLS(void);
}; // end StackLS
StackLS.cpp
// constructors
StackLS::StackLS(void)
// default constructor
{
topItem = 0;
} // end default constructor
StackLS::StackLS(const StackLS& aStack)
// copy constructor
{
} // end copy constructor
// observers
bool StackLS::isEmpty(void) const
// returns true if this stack is empty
// false otherwise
{
return topItem == 0;
} // end isEmpty
bool StackLS::isFull(void) const
// returns true if this stack is full
// false otherwise
{
return false;
} // end isFull
elemType StackLS::top(void) const
// precondition: this stack is not empty
// returns top element in this stack
{
// return (*topItem).data;
return topItem->data;
} // end top
// transformers
void StackLS::push(const elemType& item)
// precondition: this stack is not full
// adds item to this stack
{
Node *newNode = new Node;
newNode->data = item;
newNode->next = topItem;
topItem = newNode;
} // end push
void StackLS::pop(void)
// removes top element from this stack if exist
// remains empty otherwise
{
if (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end pop
void StackLS::makeEmpty(void)
// makes this stack empty
{
while (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end makeEmpty
// destructor
StackLS::~StackLS(void)
{
//while (!isEmpty())
// pop();
while (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end destructor
Here is the main.cpp that I have so far.
main.cpp
#include <iostream>
#include <string>
#include "StackLS.h"
using namespace std;
do {
int main()
{
char answer;
char n;
StackLS stack;
cout << " ********** MENU ********** " << endl;
cout << " 1. Basic Brackets () " << endl;
cout << " 2. Standard Brackets ()[]{} " << endl;
cout << " 3. User-Defined brackets " << endl;
cout << " Please enter your choice: " << endl;
switch (choice){
case 1:
cout << "Current Setting: () " << endl;
cout << "Enter your expression followed by a ; : " << endl;
do {
cin >> answer;
while (answer != ;)
}
} // end main
}
while (choice != 'n' || 'N')
Again I am wondering how I would use the stack I have shown you in this program (main.cpp). I am a little confused on why I would use stack and why. Any help is appreciated. Thanks. The main.cpp may not be right but again I am learning and that is why I am here to learn more. Thanks
When you see an opening brace, you push it onto the stack. When you see a closing brace, you make sure it is the counterpart of the brace on top of the stack, then pop it off. When your input is done, you make sure the stack is empty.