Class variable not reachable from class method - c++

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
}

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].

How to index array of pointers to arrays [queue]?

I am trying program a queue with arrays in C++.
I used this approach https://stackoverflow.com/a/936709/7104310 as shown below.
My question: How can I index the arrays to fill them?
In a normal 2d-array it would be arr[3][2] for example. But I do not know how to do this with pointers. The question hat not been answered in the Solution upon.
Thank you!
#include <iostream>
#define MAX_SIZE 3
using namespace std;
// ary[i][j] is then rewritten as
//arr[rear*capacity + front]
// Class for queue
class msg_queue
{
char **arr; // array to store queue elements
int capacity; // maximum capacity of the queue
int front; // front points to front element in the queue (if any)
int rear; // rear points to last element in the queue
int count; // current size of the queue
public:
msg_queue(int size = MAX_SIZE, int slot_length = MAX_SIZE); // constructor
void dequeue();
void enqueue(char x);
char peek();
int size();
bool isEmpty();
bool isFull();
};
// Constructor to initialize queue
msg_queue::msg_queue(int size, int slot_length)
{
arr = new char*[size];
for (int i = 0; i < size; ++i) {
arr[i] = new char[slot_length];
}
capacity = size;
front = 0;
rear = -1;
count = 0;
}
// Utility function to remove front element from the queue
void msg_queue::dequeue()
{
// check for queue underflow
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
cout << "Removing " << arr[front] << '\n';
front = (front + 1) % capacity;
count--;
}
// Utility function to add an item to the queue
void msg_queue::enqueue(char item)
{
// check for queue overflow
if (isFull())
{
cout << "OverFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
cout << "Inserting " << item << '\n';
rear = (rear + 1) % capacity;
arr[rear] = item; //ERROR HERE
count++;
}
// Utility function to return front element in the queue
char msg_queue::peek()
{
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
return arr[front]; //ERROR HERE
}
Well, it's still arr[3][2].
Although arrays are not pointers, the way we use them is effectively using a pointer because of the way they work and the way their name decays.
x[y] is *(x+y), by definition.
That being said, I would recommend you drop the 2D dynamic allocation (which is poison for your cache) and create one big block of Width×Height chars instead. You can use a little bit of maths to provide 2D indexes over that data.
Also you forgot to free any of that memory. If you use a nice std::vector to implement my suggested 1D data scheme (or even if you hire a vector of vectors, but ew!) then it'll be destroyed for you. Of course if you could do that then you'd probably be using std::queue…

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.

Stack (Data structure) implementation

So I'm just starting to learn about data structures through a course on Coursera and I learned that it's possible to create a stack data structure by using an array. I was just wondering if what I have written is what a stack is supposed to do.
#include <iostream>
using namespace std;
const int MAX_SIZE = 10000;
class Stack {
public:
Stack();
~Stack();
void push(int n);
void pop();
int top();
bool isEmpty() const;
void print() const;
private:
int* array [MAX_SIZE];
int curNum;
};
Stack::Stack() {
curNum = 0;
}
Stack::~Stack() {
for (int i = 0; i < curNum; ++i)
delete array[i];
}
void Stack::push(int n) {
if (curNum >= MAX_SIZE) {
cout << "reached maximum capacity...can't add an element\n";
return;
}
array[curNum] = new int(n);
curNum++;
}
void Stack::pop() {
delete array[curNum];
curNum--;
}
int Stack::top() {
return *array[curNum];
}
void Stack::print() const{
for (int i = 0; i < curNum; ++i)
cout << *array[i] << endl;
}
bool Stack::isEmpty() const{
return curNum == 0;
}
int main () {
Stack stack;
stack.push(5);
stack.print();
stack.pop();
}
Also, I see that a lot of people don't use dynamic memory allocation for this kind of task. Is there a reason why? It seems like specifying a size for the array at compile time might lead to insufficient memory or over-allocating memory to me
Yes, this is one way to implement a stack. The important thing that defines a stack is LIFO (last in, first out). So as long as you are only adding to and removing from the top, then that is a stack. Think of it as a stack of dishes; if 10 dishes are put one by one into a stack, and then one by one removed from said stack, the first dish put on will also be the last dish removed. You can't remove a dish that's not at the top, as it is covered by all the dishes above it. The same is true with a stack data structure.
So your implementation is indeed a stack.
The stack we use when we want something in reverse order and stack also takes constant time means O(1) time to push and pop means to remove or to add it will work much faster

error: request for member '..' in 'this', which is of non-class type '--* const'

My first ever question here. Please excuse me, I have just entered into C++ and was starting up with DS. STACK!!!
My code: I think
using namespace std;
typedef char stackElement;
class Stack
{
public:
stackElement *contents; //dynamically allocated: as we do not know what would be the size of our array.
int top, maxSize; // current Top index in the array
//max size of the array; we need it to know if the array is full
Stack(int maxSize)
{
contents = new stackElement(maxSize);
this.maxSize = maxSize;
if(contents == NULL)
{
cout<<"Insufficient memory";
exit(1);
}
top = -1;
}
~Stack()
{
delete [] contents;
contents = NULL;
maxSize = 0;
top = -1;
}
bool isEmpty()const
{
return top < 0;
}
bool isFull() const
{
return top == maxSize - 1;
}
void push(stackElement element)
{
if(isFull())
{
cout<<"STACK IS ALREADY FULL";
exit(1);
}
top = top + 1;
contents[top] = element;
}
};
int main()
{
cout<<"STACK IMPLEMENTATION";
int i = 1;
Stack s1(i);
s1.push('a');
s1.push('1');
return 0;
}
I am getting this error:
error: request for member 'maxSize' in 'this', which is of non-class type 'Stack* const'
If at all, you'd have to write this->maxSize = maxSize;, since this is a pointer.
But better not to write that at all and instead use the constructor-initializer list:
explicit Stack(int m)
: contents(new stackElement[m]), top(-1), maxSize(m)
{
// nothing else to do
}
I also added explicit so you don't accidentally convert 5 into a Stack.
You also wrote the array initialization wrong.
Also, you don't need to check that contents is not null: When new fails, it exits with an exception, it does not return a null pointer. (That behaviour would make no sense when you think in terms of objects.)
It is crucial to note that you have at most one naked new-expression in your constructor. Anything else is an exception-safety disaster, and a sign that you need to refactor and use single-responsibility resource-managing classes.
The destructor should just be: ~Stack() { delete [] contents; } Everything else is pointless waste.
Imagine you had to pay for every line of code you write. Be patient, lose the source, think.
Write
this->maxSize = maxSize;
instead of
this.maxSize = maxSize;
The this is a pointer type, not a reference type
this->maxSize instead of this.maxSize