Reputation: 1418
I'm trying to add two Priority Queues to each other by overloading the "+" operator.
// Overloading add operator (+)
template <class T> PrioQueue<T> operator + (PrioQueue<T> &a, PrioQueue<T> &b) {
// Create a new queue that's big enough to hold our 2 queues
PrioQueue<T> newPrioQueue(a.num_items + b.num_items);
// Push all items to the new queue
// all items will be sorted on pushtime (get it? Instead of runtime? Haha... Ha...)
for (T * element = a.bottom_; element < a.bottom_ + a.num_items; element++) {
newPrioQueue.push(*element);
std::cout << newPrioQueue;
}
// Push all items to the new queue
// all items will be sorted on pushtime
for (T * element = b.bottom_; element < b.bottom_ + b.num_items; element++) {
newPrioQueue.push(*element);
std::cout << newPrioQueue;
}
// This one is needed - why?
newPrioQueue.sort();
std::cout << newPrioQueue;
// New queue is done, return it.
return newPrioQueue;
}
This is my PrioQueue's push
function:
void push(T t) {
if (!full()) {
*top_ = t;
top_++;
num_items++;
// Sort items using qsort
qsort(bottom_, num_items, sizeof(T), compareFunction);
} else {
std::cout << "Queue is full" << endl;
}
};
As you can see, the PrioQueue will get sorted after every push
. However, one last sort is needed after combining the two arrays! Check this output:
Queue has 1 item(s): 429
Queue has 2 item(s): 429|123
Queue has 3 item(s): 429|123|24
Queue has 4 item(s): 429|123|24|24
Queue has 5 item(s): 429|123|24|24|3
Queue has 6 item(s): 429|123|24|24|3|2
Queue has 7 item(s): 24|123|24|429|3|2|1
Queue has 7 item(s): 429|123|24|24|3|2|1
The second to last line is the bug. It suddenly scrambles all the data!
Why is this happening?
EDIT: Here's my CompareFunction:
static int compareFunction (const void * a, const void * b) {
// Relies on overloading of the "<" operator with non-std objects
return (*(T*)a < *(T*)b);
}
This is the input:
intQueue1.push(24);
intQueue1.push(429);
intQueue1.push(123);
intQueue2.push(1);
intQueue2.push(2);
intQueue2.push(3);
intQueue2.push(24);
intQueue3 = intQueue1 + intQueue2;
Upvotes: 2
Views: 129
Reputation: 29431
I may be wrong but your compareFunction
:
static int compareFunction (const void * a, const void * b) {
// Relies on overloading of the "<" operator with non-std objects
return (*(T*)a < *(T*)b);
}
Is supposed to return 1, 0 or -1 and it return true or false...
Upvotes: 3
Reputation: 254431
You shouldn't be using qsort
in C++ without a very good reason. Try
std::sort(bottom_, bottom_+num_items);
This will compare using <
, so there's no need to provide a comparator if your type overrides that operator.
If you really want to use qsort
for some reason, then beware that it only works for trivially copyable types, and needs a different form of comparator, returning a negative, zero or positive value to indicate respectively less than, equal or greater than. You'd need something like
T & aa = reinterpret_cast<T&>(a);
T & bb = reinterpret_cast<T&>(b);
if (aa < bb) return -1;
if (bb < aa) return 1;
return 0;
Upvotes: 1