int value changing when calling a function

I have created a queue using an array, and I have a function that returns the front value and also a isEmpty function. The front() function calls the isEmpty() to check if the queue is empty or not so it can return a value. However, when I call the isEmpty function, the int variables that I am using to keep track of the front and back of the queue change value. It only seems to happen in these two functions, everytime front() calls isEmpty apart from the very first time the call is made, and I can not figure out why.

In the main function, the first call to isEmpty works fine, but everytime after that when either isEmpty() is called or front() the values of frontQ and rearQ changes inside the isEmpty() function. Luckily the info given back is still correct on most of the calls, but I do not understand why these values are changing. frontQ seems to change to a value of something like 16843009 and rearQ changes to 1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <iostream>
#include "queueArray.h"
#include <string>

int main()
{
		queueArray QA(10);
			std::cout << "Queue empty : " << QA.isEmpty() << "\n";
			QA.enqueue(2);
			QA.print();
			QA.enqueue(4);
			QA.enqueue(6);
			QA.enqueue(8);
			QA.print();
			std::cout << "Front of queue : " << QA.front() << "\n";
			std::cout << "Queue empty : " << QA.isEmpty() << "\n";
			QA.dequeue();
			QA.dequeue();
			QA.dequeue();
			QA.print();
			std::cout << "Front of queue : " << QA.front() << "\n";
			std::cout << "Queue empty : " << QA.isEmpty() << "\n";
			QA.dequeue();
			std::cout << "Front of queue : " << QA.front() << "\n";
			std::cout << "Queue empty : " << QA.isEmpty() << "\n";
			break;
  }







#pragma once

class queueArray
{

private:
	int size;
	int frontQ = -1;
	int rearQ = -1;
	int* Qarray;

public:
	queueArray(int s);
	~queueArray();

	void enqueue(int value);
	void dequeue();
	int front();
	bool isEmpty();
	void print();	//only for debug purposes


};





#include <iostream>
#include "queueArray.h"

queueArray::queueArray(int s) : size(s)
{
	Qarray = new int [size];
}

queueArray::~queueArray()
{
	delete []Qarray;
}

void queueArray::enqueue(int value)
{
	if (frontQ == -1)
	{
		frontQ = 0;
		rearQ = 0;
	}
	else if(rearQ == size - 1)
	{
		std::cout << "Queue is full, cannot enqueue\n";
		return;
	}
		
	Qarray[rearQ] = value;
	rearQ++;

}

void queueArray::dequeue()
{
	if(frontQ == -1)
	{
		std::cout << "Queue is empty \n";
		return;
	}
	else if (frontQ == rearQ)
	{		
		std::cout << "Dequeing : " << Qarray[frontQ] << "\n";
	}
	else
	{
		std::cout << "Dequeing : " << Qarray[frontQ] << "\n";
		frontQ++;
	}

	if (frontQ == rearQ)
	{
		frontQ = rearQ = -1;
	}
}


int queueArray::front()
{
	if (!isEmpty())
	{
		return Qarray[frontQ];
	}
	else
	{
		std::cout << "Queue is empty\n";
		return -1;
	}
	
}

bool queueArray::isEmpty()
{
	return (frontQ == -1 && rearQ == -1);
}

void queueArray::print()
{
	std::cout << "Queue contents : ";
	int temp = frontQ;
	while (temp != rearQ )
	{
		std::cout << Qarray[temp] << " ";
		temp++;
	}
	std::cout << "\n";
}



Last edited on
Hello DonnaPin,

I am having a herd time understand your question. The function "isEmpty" only compares the variables. Neither variable changes value.

And there is nothing in the "front" function that changes any variables value.

I made some changes to "main" to make it easier to figure out what is wrong:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int main()
{
    
    queueArray QA(10);

    std::cout << "Queue empty : " << std::boolalpha << QA.isEmpty() << " // 1st call to is Empty.\n\n";
    QA.enqueue(2);
    QA.print();

    QA.enqueue(4);
    QA.enqueue(6);
    QA.enqueue(8);
    QA.print();

    std::cout << "Front of queue : " << QA.front() << "\n";
    std::cout << "Queue empty : " << std::boolalpha << QA.isEmpty() << " // 2nd call to is Empty.\n\n";

    QA.dequeue();
    QA.dequeue();
    QA.dequeue();
    QA.print();

    std::cout << "Front of queue : " << QA.front() << "\n";
    std::cout << "Queue empty : " << std::boolalpha << QA.isEmpty() << " // 3rd call to is Empty.\n\n";

    QA.dequeue();

    std::cout << "Front of queue : " << QA.front() << "\n";
    std::cout << "Queue empty : " << std::boolalpha << QA.isEmpty() << " // 4th call to is Empty.\n";

    //break;  // <--- There is nothing to break out of. Used here it is a compiler error.
    return 0;  // <--- Not required, but makes a good break point for testing.
}

Breaking up "main" as I did helps to figure out where you are at and narrow down where it goes wrong.

I made some minor changes in the "queueArray.cpp", but they are minor and put there for debugging use.

The output I get with MSVS 2017 is:

Queue empty : true  // 1st call to is Empty.

Queue contents : 2

Queue contents : 2 4 6 8

Front of queue : 2
Queue empty : false  // 2nd call to is Empty.

Dequeing : 2
Dequeing : 4
Dequeing : 6
Queue contents : 8

Front of queue : 8
Queue empty : false  // 3rd call to is Empty.

Dequeing : 8
Queue is empty
Front of queue : -1
Queue empty : true  // 4th call to is Empty.


Is this what you get or is it something else?

Andy
> However, when I call the isEmpty function, the int variables that I am using
> to keep track of the front and back of the queue change value.
perhaps out of range access
you should post your actual program, as this one doesn't even compile


some things:
- in enqueue() you consider rearQ == size - 1 as full, however size-1 is a valid index for an array
- in dequeue() you say frontQ == rearQ is an empty queue, however you still dequeue that element
- ¿does rearQ points to the last element or one past the last element?
- you could wrap around the array in order to use the space available after a dequeue operation
- ¿why enqueue() and dequeue() don't make use of isEmpty() and instead define their own empty criteria?
Perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <iomanip>

class queueArray {
private:
	size_t size {};		// Max size of queue
	size_t noelems {};		// No of current elements
	size_t frontQ {};		// Index of front element
	size_t rearQ {};		// Index of rear element
	int* Qarray {};

public:
	queueArray(size_t s);
	~queueArray();

	void enqueue(int value);	// To rear
	void dequeue();				// From front
	int front() const;			// Obtain front element
	bool isEmpty() const;		// Is queue empty
	bool isFull() const;		// Is queue full
	void print() const;			// Only for debug purpose
};

queueArray::queueArray(size_t s) : size(s), Qarray(new int[s]) {}
queueArray::~queueArray() { delete[] Qarray; }

void queueArray::enqueue(int value) {
	if (isFull()) {
		std::cout << "Queue is full, cannot enqueue\n";
		return;
	}

	Qarray[rearQ] = value;
	rearQ = (rearQ + 1) % size;
	++noelems;
}

void queueArray::dequeue() {
	if (isEmpty()) {
		std::cout << "Queue is empty \n";
		return;
	}

	std::cout << "Dequeing: " << Qarray[frontQ] << '\n';
	frontQ = (frontQ + 1) % size;
	--noelems;
}

int queueArray::front() const {
	if (!isEmpty())
		return Qarray[frontQ];

	std::cout << "Queue is empty\n";
	return -1;
}

bool queueArray::isEmpty() const {	return noelems == 0; }
bool queueArray::isFull() const { return noelems == size; }

void queueArray::print() const {
	std::cout << "Queue contents : ";

	for (size_t temp = frontQ, el = 0; el < noelems; ++el, temp = (temp + 1) % size)
		std::cout << Qarray[temp] << ' ';

	std::cout << '\n';
}

int main()
{
	queueArray QA(10);

	std::cout << "Queue empty : " << std::boolalpha << QA.isEmpty() << "\n";

	QA.enqueue(2);
	QA.print();
	QA.enqueue(4);
	QA.enqueue(6);
	QA.enqueue(8);
	QA.print();

	std::cout << "Front of queue : " << QA.front() << "\n";
	std::cout << "Queue empty : " << std::boolalpha << QA.isEmpty() << "\n";

	QA.dequeue();
	QA.dequeue();
	QA.dequeue();
	QA.print();

	std::cout << "Front of queue : " << QA.front() << "\n";
	std::cout << "Queue empty : " << std::boolalpha << QA.isEmpty() << "\n";

	QA.dequeue();
	std::cout << "Front of queue : " << QA.front() << "\n";
	std::cout << "Queue empty : " << std::boolalpha << QA.isEmpty() << "\n";
}



Queue empty : true
Queue contents : 2
Queue contents : 2 4 6 8
Front of queue : 2
Queue empty : false
Dequeing: 2
Dequeing: 4
Dequeing: 6
Queue contents : 8
Front of queue : 8
Queue empty : false
Dequeing: 8
Front of queue : Queue is empty
-1
Queue empty : true

Sorry for ignoring the answers for so long, I was away from my PC for a few days.

I have looked at the code again, and it seems that when i follow the code through using breakpoints, the two ints do change values, but then they change to what they should be after the function ends, so it does seem that it is actually working correctly, and it must have been somewhere else causing my issues.

some things:
- in enqueue() you consider rearQ == size - 1 as full, however size-1 is a valid index for an array
- in dequeue() you say frontQ == rearQ is an empty queue, however you still dequeue that element
- ¿does rearQ points to the last element or one past the last element?
- you could wrap around the array in order to use the space available after a dequeue operation
- ¿why enqueue() and dequeue() don't make use of isEmpty() and instead define their own empty criteria?


First point : Yup I hadnt noticed that, I will need to rework it again.
- Im not sure where you mean with this one, the first frontQ == rearQ is dequeue, is to dequeue the last remaining element, then the second frontQ== rearQ is for when the last element is dequeued. At least thats my thinking behind it, it might not actually be working like that.
-rearQ points to the last element
- Is that the same as a circularArray, I have only last week learned that circular arrays were a thing, and I have implemented one into the queue, but I am trying to code both types as I am learning data structures, and want the practice
- I do not know, I will fix that though. Ive been learning for about a year now, and still making dumb mistakes like this.
Topic archived. No new replies allowed.