Queue realisation C++ - c++

My realization of queue works in a strange way: when I enqueue new elements - all is right, but when I start to dequeue - it removes the last added element despite the fact that at this moment my head is 1 and tail is bigger. What are the pecularities of indexing in C++? Why does it behave like this?
Here is my full code:
https://hastebin.com/odibusacuk.cpp
class Queue{
public:
int head=1;
int tail=1;
int q[MAX];
int Queue::enqueue(int x){
if (isFull()){
return 0;}
else {
q[tail]=x;
cout << tail << " here is a tail\n";
if (tail==sizeof(q)){
cout << tail << " this is tail\n" ;
tail=1;}
else {
tail=tail+1;
}
return x;
}
}
int Queue::dequeue(){
if(isEmpty()){
cout << " the queue is empty\n";
return 0;}
else {
int x=q[head];
if (head==sizeof(q)){
head=1;}
else {
head=head++;
return x;}
}
return 0;
}

The problem you are having is because when you do something like
cout << k.enqueue(4) << " " << k.enqueue(9) << ' ' << k.enqueue(6) << " " << k.enqueue(3) << " enqueued\n ";
it is not specified in what order these functions will be called.
In your example, they are being called from right to left.
This means your queue is actually
{ 0, 3, 6, 9, 4 }
0 is there since your are skipping element 0 and going directly to element 1.
Your head is pointing to 1, thus you will dequeue 3.
You can read more here.

Related

C++ Dynamically allocate a structure which contains an union[vec or map] twice leads to a bad_alloc error

I have a bunch of tuples (int array[N], string message) to store. I want to be able to add/delete a lot of elements from this array very quickly but, most importantly, given another array array2, I want to find every string such that for all i : array[i] <= array2[i] (not implemented yet).
Thus, I thought about using a tree of height N where a leaf is a message. If it is a leaf, it should contain a vector if it's a node, it should contain a map.
I am using an union to manage whether a tree is a leaf or a node.
My delete function should delete the leaf and all the nodes that lead only to this leaf.
I can insert a message (or multiple different messages). However, I can't reinsert a message that I previously deleted. It raises a bad_alloc error.
#include <iostream>
#include <map>
#include <vector>
using namespace std;
struct Node{
enum{LEAF, NODE} tag;
union {
std::map<int, struct Node*> map;
std::vector<std::string> msg;
};
Node(std::string m){
tag = LEAF;
cout << "Flag 1 : Crashing here, for some reasons a map is allocated" << "\n";
msg.push_back(m);
cout << "Flag 2 : Did you manage to fix it ?" << "\n";
}
Node(){
tag = NODE;
map = std::map<int, struct Node*>();
}
~Node(){
if (tag==NODE){
map.~map();
} else {
msg.~vector();
}
}
};
void insert(int* array, int size, Node* node, std::string msg){
cout << "Insert\n";
if (size > 1){
if (!node -> map.count(array[0])){
node->map[array[0]] = new Node();
}
insert(array+1, size-1, node->map[array[0]], msg);
} else {
if (!node->map.count(array[0])){
cout << "Case 1\n";
node -> map[array[0]] = new Node(msg);
}
else{
cout << "Case 2\n";
node -> map[array[0]]->msg.push_back(msg);
}
}
}
bool find(int * array, int size, Node * node){
if (!node -> map.count(array[0])){
return false;
}
if (size==1){
return true;
}
return find(array+1, size-1, node->map[array[0]]);
}
std::vector<std::string> find_vec(int * array, int size, Node * node){
if (!node -> map.count(array[0])){
return std::vector<std::string>();
}
if (size==1){
if (!node -> map.count(array[0])){
return std::vector<std::string>();
}
return node -> map[array[0]]->msg;
}
return find_vec(array+1, size-1, node->map[array[0]]);
}
void print_array(std::vector<std::string> v){
for (auto & elem : v){
cout << elem << " ";
}
cout << "\n";
}
void erase(int * array, int size, Node * node){
std::vector<Node*> vec;
int i = 0;
Node *t = node;
while (i < size){
if (t -> map.count(array[i])){
vec.push_back(t);
t = t-> map[array[i]];
} else
break;
i++;
}
if (i == size){
// Deleting the leaf
cout << "Deleting Leaf\n";
delete t;
cout << "Deleting vec [" << size-1 << "] elem " << array[size-1] << "\n";
cout << "Deleted ? " << vec[size-1]->map.erase(array[size-1]) << "\n";
// Deleting the path if it has no other leaf
cout << "Delete Path\n";
for (i = size-1; i > 0; i--){
//cout << "debut loop " << i << "\n";
//vec[i-1]->map.erase(array[i-1]);
if (!vec[i] -> map.size()){
delete vec[i];
cout << "Deleting vec [" << i-1 << "] elem " << array[i-1] << "\n";
cout << "Deleted ? " << vec[i-1]->map.erase(array[i-1]) << "\n";
}
else
break;
//cout << "fin loop\n";
}
}
}
int main()
{
Node * Tree = new Node;
for (int k = 0; k < 2; k++){
cout << "k = " << k << "\n---------------------------------------------------------------------------------------------\n";
int size = 4;
int array[4] = {0,1,2,3};
std::string m1 = "Random message that I want to store as many times as I want";
insert(array, size, Tree, m1);
cout << "find : " << find(array, size, Tree) << "\n";
std::vector<std::string> vec1 = find_vec(array, size, Tree);
cout << "vec ";
print_array(vec1);
cout << "-------------------\n";
erase(array, size, Tree);
cout << "We should find the message \n";
print_array(vec1);
cout << "-------------------\n";
cout << "We should not find the message \n";
vec1 = find_vec(array, size, Tree);
print_array(vec1);
cout << "-------------------\n";
}
return 0;
}
A union should be treated with care, especially when used with non-trivial members like in your example. Specifically of interest is this passage from cppreference:
If a union contains a non-static data member with a non-trivial
special member function (copy/move constructor, copy/move assignment,
or destructor), that function is deleted by default in the union and
needs to be defined explicitly by the programmer.
If a union contains a non-static data member with a non-trivial
default constructor, the default constructor of the union is deleted
by default unless a variant member of the union has a default member
initializer .
The map member is not constructed and therefore you cannot just start using it.
I recommend using std::variant as a safe alternative to a raw union. Your example would look like the following without a need for your enum:
struct Node {
std::variant<std::map<int, Node*>, std::vector<std::string>> data;
Node(std::string m){
data.emplace<1>();
cout << "Flag 1 : Crashing here, for some reasons a map is allocated" << "\n";
std::get<1>(data).push_back(m);
cout << "Flag 2 : Did you manage to fix it ?" << "\n";
}
// ...
};

My dynamically linked queue improperly outputs three return functions when called in the same output stream

For an assignment I was tasked with creating a queue with linked lists. Our professor has given us the test code to insure the program is working properly and for grading. My serve function returns a character. However in the main(), the function is called twice within one cout statement, and it returns the character in incorrect order. The getSize function is also called, however it does not seem to do anything.
cout << boolalpha;
Queue q1 = Queue();
q1.append('m');
q1.append('a');
q1.append('b');
q1.append('b');
q1.display();
cout << q1.serve() << " " << q1.serve() << " " << q1.getSize() << endl;
the display outputs: m a b b. However the cout shows as: a m 4. This should obviously come out as: m a 2.
If i separate the serve and the getSize functions, it works just fine, i.e. cout << q1.serve() << " "; cout << q1.serve() << " "; cout << q1.getSize() << " ";
Below I have posted the code for the linked queue. I imagine I have made a mistake with my node pointers, however I have drawn pictures and re-written the code to no avail.
I also apologize if Ive improperly formatted this as it is my first posting. Thank you.
#include <iostream>
using namespace std;
struct Node {
char data;
Node* next;
};
class Queue {
private:
Node* front, * rear;
int size;
public:
Queue();
void append(char);
char serve();
bool isEmpty();
bool isFull();
int getSize();
void display();
};
Queue::Queue() {
front = rear = nullptr;
size = 0;
}
void Queue::append(char v) {
Node* p = new Node;
p->data = v;
p->next = nullptr;
if (size == 0) {
front = rear = p;
size++;
}
else if (size == 1) {
front->next = p;
rear = p;
size++;
}
else {
rear->next = p;
rear = p;
size++;
}
}
char Queue::serve() {
if (front != nullptr) {
Node* temp = front;
char v = temp->data;
front = front->next;
delete temp;
size--;
return v;
}
}
bool Queue::isEmpty() {
return size == 0;
}
bool Queue::isFull() {
return false;
}
int Queue::getSize() {
return size;
}
void Queue::display() {
Node* runner = front;
while (runner != nullptr) {
cout << runner->data << " ";
runner = runner->next;
}
cout << endl;
}
int main() {
cout << boolalpha;
Queue q1 = Queue();
q1.append('m');
q1.append('a');
q1.append('b');
q1.append('b');
q1.display();
cout << endl << q1.isEmpty() << " " << q1.isFull() << " " << q1.getSize() << endl;
cout << q1.serve() << " " << q1.serve() << " " << q1.getSize() << endl;
q1.display();
cout << endl;
/*cout << q1.isEmpty() << " " << q1.isFull() << " " << q1.getSize() << endl;
char a = q1.serve(); char b = q1.serve();
cout << a << " " << b << " " << q1.getSize() << endl;*/
}
I'll give you a big hint: Your output is "a m 4", not "m a 4". The remainder of the answer is below...
.
.
.
.
.
.
(edit: added more explanation)
The cout is running the arguments right to left, because of the associativity of the << operator. So it's getting the size, then getting the first item in the queue, then getting the next one. Even though the operator itself is Left-to-Right, in order to apply them in that order, it's evaluating the arguments right to left.
Think of it this way, while it's required to apply the operators on the left before it applies the ones on the right, it's still evaluating the argument on the right of the operator before it evaluates the one on the left.
This is fundamentally about how the stack works. It's loading the evaluation of the arguments and operators right to left so that it can apply the operators in the reverse order.
Since the operators are all the same precedence, it's pushing the right most operand, then the right most operator, then that' operator's left operand, which is everything to the left.
If your operators are L-R associative, that means that the operands are evaluated R-L before being operated on L-R.
Just do
cout << q1.serve() << " ";
cout << q1.serve() << " ";
cout << q1.getSize() << endl;

C++ -Problems in Stacking an array

I've been trying to figure out why my code isn't working correctly for the past few hours. Everything looks perfectly fine to me unless it's something I don't know about. I have asked my professor, but he can't seem to figure it out either. This code will completely ignore the if else statement in the push member function and will keep pushing after reaching the limit (in this case it's 5 elements). When it goes over the 5th element, and I check for the top, it shows the first implementation (element 0). I tried changing around my code by switching the member functions outside the class via scope resolution, but it's still no use. A different set of eyes would be greatly appreciated.
#include <iostream>
#include <cctype>
using namespace std;
class Stack
{
private:
static const int size = 5;
double myarr[size];
int t;
public:
Stack() { t = -1; }
void push(double element);
void pop();
void top();
void menu();
};
void Stack::push(double element)
{
if (t < size) {
t++;
myarr[t] = element;
}
else
cout << "Stack Limit Reach !!!" << endl;
}
void Stack::pop()
{
if (t >= 0) {
cout << "Element : " << myarr[t] << " was popped off the Stack " << endl;
t--;
}
else
cout << "No more elemnts in the Stack !!!" << endl;
}
void Stack::top()
{
if (t >= 0) {
cout << "Element : " << myarr[t] << " is at the top of the Stack " << endl;
}
else
cout << "No more elemnts in the Stack !!!" << endl;
}
void Stack::menu()
{
char choice = 'y';
int pick;
double elem;
while (toupper(choice) == 'Y');//while(choice == 'y' || choice == 'Y');
{
cout << "1. Push" << endl;
cout << "2. Pop" << endl;
cout << "3. Top" << endl;
cout << "4. Exit" << endl;
cin >> pick;
switch (pick)
{
case 1:
cout << "Enter the element: ";
cin >> elem;
cout << endl;
push(elem);
break;
case 2:
pop();
break;
case 3:
top();
break;
case 4:
choice = 'N';
break;
default:
cout << "Please select 1-4" << endl;
}
system("pause");
}
}
int main()
{
Stack obj;
obj.menu();
};
In your example code, the stack's size is 5 (which means array myarr has valid indices 0 through 4).
void Stack::push(double element)
{
if (t < size) {
t++;
myarr[t] = element;
}
else
cout << "Stack Limit Reach !!!" << endl;
}
Consider the case when t here is 4. The if tests true, so the block to add to myarr is entered. First thing that happens is you increment t, which is now 5. Then you use that as the index to store the value into myarr, which is out of bounds.
Try something like:
void Stack::push(double element)
{
if (t < size) {
myarr[t++] = element;
}
else
cout << "Stack Limit Reach !!!" << endl;
}
You are allowing 6 elements to be pushed onto the stack, and there's only room for 5.
Change:
if (t < size) {
t++;
to:
if (t < size-1) {
t++;
I understood your problem when you are searching for the top element you are not getting because whenever the stack becomes full for ex:-
assume you are inserting(below mentioned code) 5th element in 4th index it will be inserted and the value of t get incremented to 5 due to t++.
void Stack::push(double element)
{
if (t < size) {
t++;
myarr[t] = element;
}
else
cout << "Stack Limit Reach !!!" << endl;
}
but at the same time when you call top() function it checks for the index, and obviously 5 is greater that 0 so it enters the loop but index 5 contains '\0'
Character so there is an ambiguity with compiler
void Stack::top()
{
if (t >= 0) {
cout << "Element : " << myarr[t] << " is at the top of the Stack " << endl;
}
else
cout << "No more elemnts in the Stack !!!" << endl;
}
So the change that is required for the above code is just put a if statement by saying the compiler that if the stack is full then decrement t value by 1
void Stack::top()
{
if (t >= 0) {
if(t==size){t--;}
cout << "Element : " << myarr[t] << " is at the top of the Stack " << endl;
}
else
cout << "No more elemnts in the Stack !!!" << endl;
}
This may give you correct result
You skip myarr[0] then 5th element is saved to myarr[5] that is 6th element in myarr! (Accessing to elements of an array by index is zero based in C++)
Change:
Stack() { t = -1; }
to:
Stack() { t = 0; }
and
if (t < size) {
t++;
myarr[t] = element;
to:
if (t < size) {
myarr[t++] = element;

Visual Studio C++ 2k15 - Getting error on pointer address

this is my first post on Stack Overflow :)
Sorry if I seems egoistic, but I have an exam tomorrow and I'm facing a problem that I cannot solve. Hope to find here an answer, I tried to find out if there was already an opened 3d, but I cannot find it.
Here's my problem:
I'm writing a code in C++, using the pointer. Because of I retrieve always the same error on a larger code, I tried with an easier one, but the error persists.
The code is the following:
#include <iostream>
using namespace std;
struct EXAMPLE {
int value;
EXAMPLE *next;
};
int insertnew(EXAMPLE *&sorting, EXAMPLE val);
int printlist(EXAMPLE *&sorting);
int main() {
int i;
EXAMPLE new;
EXAMPLE *list = NULL;
for (i = 0; i < 3; i++)
{
cout << "value: " << endl;
cin >> new.value;
insertnew(list, new);
}
printlist(list);
system("Pause");
return 0;
}
int insertnew(EXAMPLE *&sorting, EXAMPLE val){
EXAMPLE *temp;
temp = new EXAMPLE;
temp->value = val.value;
temp->next = sorting;
sorting = temp;
return 0;
}
int printlist(EXAMPLE *&sorting) {
while (sorting != 0)
{
sorting = sorting->next;
cout << sorting->next << " " << sorting->value << endl;
}
return 0;
}
It's an easy LIFO structure.
I get a bad reading access error on this line:
cout << elenco->next << " " << elenco->valore << endl;
But here's the curios thing.
If I revert the lines in this way:
int printlist(EXAMPLE *&sorting) {
while (sorting != 0)
{
cout << sorting->next << " " << sorting->value << endl;
sorting = sorting->next;
}
return 0;
}
as a FIFO structure, I got no error at all!
Can you help me understanding where the problem is?
Thanks in advance
//edit
Uops, find out my error.
The while was supposed to be a recursive function, dunno why I inserted a while, assuming it will function as a recursive function.
just solved
cout << lista->value << endl;
while (list != NULL)
{
list = list->next;
if (list != 0) {
cout << list->value << endl;
}
}
Sorry
Let's take a look at your example code:
int printlist(EXAMPLE *&sorting) {
while (sorting != 0) //As long as "sorting" is not null
{
sorting = sorting->next; //Set "sorting" to the next value
cout << sorting->next << " " << sorting->value << endl; //print the value
}
return 0;
}
Just play this code through if you have only one element in your LIFO list.
int printlist(EXAMPLE *&sorting) {
while (sorting != 0) //"sorting" is not null
{
sorting = sorting->next; //Set "sorting" to the next value, which is null
cout << sorting->next << " " << sorting->value << endl; //crash because "sorting" is null
}
return 0;
}
This will happen every time you hit the last element.
You can change your code to a do-while-loop with an additional if, or add an if with a break within your current loop. But I would recommend to go with a for-loop on this one.
Also you don't need to pass the pointer by reference. You even shouldn't do it, as you don't want to change your list when printing it (as your current code does...)
How about something like this:
int printlist(EXAMPLE * sorting) {
for (EXAMPLE * current = sorting; current != 0; current = current->next)
{
cout << current << " " << current->value << " -> " << current->next << endl;
}
return 0;
}
I also changed the output a little bit to show more interesting data.
You are trying to access the tail of the list when sorting->next reaches the last element. With the second code you access only list elements.
Clear, thanks
I also tried another version
int printlist(EXAMPLE *list) {
if (list != NULL)
{
cout << list->value << "-> " << list->next << endl;
printlist(list->next);
}
return 0;
}
and this is how it was supposed to work from the beginning. In this way by just switching the two rows inside the IF I can change from LIFO to FIFO :)

List-Search with recursion by using list library

int listRecSearch(list<int>list, const int data)
{
if (list.empty())
{
cout << "The number is not in the list, try again..." << endl;
return -1;
}
else if (list.back() == data)
{
// cout << "list.size(): " << list.size() << endl;
list.pop_back();//I needed the index begins from 0 instead of 1
return list.size();
}
else
{
// cout << "list.back(): " << list.back() << endl;
list.pop_back();
listRecSearch(list, data);
}
}
//funtion used
int main()
{
list<int>list = listGenerator(size);//generate a list with 20 random numbers.
cout << "Specify the element to be searched for: ";
cin >> data;
int position = listRecSearch(list, data);
if (position > -1)
cout << "\nFind the element at position: " << position << endl;
}
The function listRecSearch was able to display correct list.size() value and correct pop_back values. But once it returned, it always return a garbage value. I figured there were steps were still went through after return, but I can't see where and how.
There exists a code path which does not return a value. listRecSearch(list, data); should become return listRecSearch(list, data);.