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");
Related
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 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 ©) //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].
I am trying to implement a circular queue.
I have declared size of the queue in the header file and I initiated my queue using size variable via constructor.
Here are queue.h and queue.cpp files.
class Queue
{
public:
int size;
int front, rear;
int A[];
Queue(int size);
bool isEmpty();
void enqueue(int n);
int dequeue();
int Peek();
void Display();
int sizeQ();
};
Here is queue.cpp
Queue::Queue(int size)
{
int A[size];
front = rear = -1;
}
bool Queue::isEmpty(){
if((front == -1) && (rear == -1))
return true;
else
return false;
}
void Queue::Display(){
if(isEmpty()){
cout << "Its empty! Nothing to display"<<endl;
}else{
for(int i=0; i<sizeQ(); i++){
cout << A[i] << endl;
}
}
cout <<endl;
}
Here is my main
int main()
{
Queue q1(10);
q1.enqueue(20);
q1.Display();
return 0;
}
The problem: Loop inside display function does not see the size variable although I created object using size inside main. When I debug the program, I saw that size is 0, thus for loop never starts.
What I tried
int Queue::sizeQ(){
return size;
}
I tried to return size via method; however, no luck. What should I do in order to access size variable?
Currently your constructor creates a local array that gets destroyed after it completes. You don't want to do this.
If you want to set the size of an array at run time it has to be declared on the heap. To do that you should change the declaration of the array A like this in the header:
int *A;
Then in your constructor you can allocate the array on the heap:
Queue::Queue(int iSize):
size(iSize), front(-1), rear(-1)
{
A = new int[size];
}
Note the initialiser list is initialising member variables size, front and rear.
You must also deallocate your array. To do this add a destructor to your class Queue and do this:
Queue::~Queue()
{
delete [] A;
}
This will free up the memory used by A.
Queue::Queue(int size)
{
int A[size];
front = rear = -1;
}
You never initialize this->size here. Hence sizeQ() returns uninitialized value of size member.
Add this->size = size; inside the constructor.
EDIT: the int A[size] does not do what you think it does. It is creating a local array and has nothing to do with the member A. Refer to #jignatius answer to see how to fix it.
Initiate size inside constructor like below:
Queue::Queue(int nSize) //changed name of parameter to nSize to remove confusion
{
int A[size];
front = rear = -1;
size = nSize; // Initialize passed param to member variable of class
}
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.
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.
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;
}