0

I have a program in which I'm trying to implement a priority queue. In the PriorityQueue.h file I've overloaded the ostream operator <<, but when that function is called, after printing out the correct values from my queue, it prints the memory map and then my core is dumped and the program exits.

Here is the call to output the contents of my queue (this line is is located in my main.cpp file);

cout << "Printing Q1" << endl;
cout << Q1 << endl;

where Q1 is my priority queue, containing the values 10, 5 and 1 in that order.

here is my PriorityQueue.h file, at the bottom is where I've defined my overloaded ostream operator.

#include "ListT.h"
#include <ostream>
using namespace std;

//template <typename T>
template <typename T>
class PriorityQueue : private List<T>
{

public:

//constructor
PriorityQueue();
//add item to priority queue
void enqueue(T item);
//remove the item with the highest priority from the list
void dequeue();
//remove the item with the highest priority and assign its value to T& item
void dequeue(T& item);
//look at the item with highest priority and assign its value to T& item
void peek(T& item) const;
//return the size of the priority queue
int getSize() const;

//overloaded assignment operartor, performs deep copy of rhs
PriorityQueue<T>& operator =(PriorityQueue<T>& rhs);
};



//overloaded output operator
template <typename T>
ostream& operator <<(ostream& os, const PriorityQueue<T>& rhs)
{
    T item;
    PriorityQueue<T> rhsCopy = rhs;
    while(rhsCopy.getSize() > 0){
        rhsCopy.dequeue(item);
        os << item << endl;
    }

    return os;
}

//overloaded assignment operator/copy constructor
template <typename T>
PriorityQueue<T>& PriorityQueue<T>::operator =(PriorityQueue<T>& rhs) 
{
    int index = 1, size = rhs.getSize();
    T itemCopy;
    while(index < size){
        rhs->retrieve(index,itemCopy);  
        *this->enqueue(itemCopy);
        index++;
    }
    return *this;
}

#include "PriorityQueue.cpp"

Edit:

Here is the output of the program

********* TEST 1 ***********************************************
Printing Q1
10  
5
1

*** glibc detected *** ./lab8: double free or corruption (fasttop): 0x000000000132a030 ***
======= Backtrace: =========
/lib64/libc.so.6[0x397c27bfee]
./lab8[0x4020b7]
./lab8[0x401929]
./lab8[0x402447]
./lab8[0x4014e8]
./lab8[0x401430]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x397c221735]
./lab8[0x401339]
======= Memory map: ========
00400000-00404000 r-xp 00000000 08:01 19792231                          
 /mnt/sda1    /c++/school/lab8/lab8/lab8
00603000-00604000 rw-p 00003000 08:01 19792231                            
/mnt/sda1    /c++/school/lab8/lab8/lab8
0132a000-0134b000 rw-p 00000000 00:00 0                                  
[heap]
397be00000-397be20000 r-xp 00000000 fd:01 165912                         
/usr/lib64    /ld-2.15.so
397c01f000-397c020000 r--p 0001f000 fd:01 165912                         
/usr/lib64/ld-2.15.so
397c020000-397c021000 rw-p 00020000 fd:01 165912                         
/usr/lib64/ld-2.15.so
397c021000-397c022000 rw-p 00000000 00:00 0 
397c200000-397c3ac000 r-xp 00000000 fd:01 165944                         
/usr/lib64/libc-2.15.so
397c3ac000-397c5ac000 ---p 001ac000 fd:01 165944                        
/usr/lib64/libc-2.15.so
397c5ac000-397c5b0000 r--p 001ac000 fd:01 165944                         
/usr/lib64/libc-2.15.so
397c5b0000-397c5b2000 rw-p 001b0000 fd:01 165944                         
/usr/lib64/libc-2.15.so
397c5b2000-397c5b7000 rw-p 00000000 00:00 0 
397d200000-397d2fa000 r-xp 00000000 fd:01 165973                         /usr/lib64/libm-2.15.so
397d2fa000-397d4f9000 ---p 000fa000 fd:01 165973                         /usr/lib64/libm-2.15.so
397d4f9000-397d4fa000 r--p 000f9000 fd:01 165973                         /usr/lib64/libm-2.15.so
397d4fa000-397d4fb000 rw-p 000fa000 fd:01 165973                         /usr/lib64/libm-2.15.so
3980a00000-3980a15000 r-xp 00000000 fd:01 165976                         /usr/lib64/libgcc_s-4.7.2-20120921.so.1
3980a15000-3980c14000 ---p 00015000 fd:01 165976                         /usr/lib64/libgcc_s-4.7.2-20120921.so.1
3980c14000-3980c15000 rw-p 00014000 fd:01 165976                         /usr/lib64/libgcc_s-4.7.2-20120921.so.1
3988a00000-3988ae5000 r-xp 00000000 fd:01 155500                         /usr/lib64/libstdc++.so.6.0.17
3988ae5000-3988ce4000 ---p 000e5000 fd:01 155500                         /usr/lib64/libstdc++.so.6.0.17
3988ce4000-3988cec000 r--p 000e4000 fd:01 155500                         /usr/lib64/libstdc++.so.6.0.17
3988cec000-3988cee000 rw-p 000ec000 fd:01 155500                         /usr/lib64/libstdc++.so.6.0.17
3988cee000-3988d03000 rw-p 00000000 00:00 0 
7fed62cd9000-7fed62cde000 rw-p 00000000 00:00 0 
7fed62cf4000-7fed62cf7000 rw-p 00000000 00:00 0 
7fff06836000-7fff06857000 rw-p 00000000 00:00 0                          [stack]
7fff06862000-7fff06863000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)
kjh
  • 3,407
  • 8
  • 42
  • 79
  • Could you give us a minimal complete example? (I really should hotkey that question.) – Beta Nov 01 '12 at 21:52
  • Looks to me like you have failed to define a copy constructor for your PriorityQueue class. Which is strange because you have defined an assignment operator. Normally people don't bother with either. However you assignment operator is bugged and your copy constructor is non-existent. Since you invoke the copy constructor in your `operator<<` function I'm betting that's where the error lies. You should read up on the rule of three, this class is never going work until you follow it. http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three – john Nov 01 '12 at 21:56
  • BTW the correctness (or otherwise) of your code depends crucially on the List class. No-one is going to be able to diagnose the problem unless they can see that class. – john Nov 01 '12 at 22:00
  • The list class was implemented by a course instructor of mine, that file is compilable and implementable without error. (At the very least, I am trusting that this is true) – kjh Nov 01 '12 at 22:01
  • The rule of three may be the issue. I will look into it, thanks for the link – kjh Nov 01 '12 at 22:02
  • I think the crucial question will be whether the List class is following the rule of three. If it is then you probably have some other issue, but as I said can't really help without seeing that crucial piece of code. – john Nov 01 '12 at 22:09
  • It wasn't following the rule of three. after implementing a copy constructor the program works perfectly, thanks a ton. – kjh Nov 01 '12 at 22:13

1 Answers1

0

Biggest problem with your code is the fact that you templated your PriorityQueue class and then attempted to use create a ostream function in a different location.

template <typename T>
class PriorityQueue : private List<T>
{
...
}

This is implementation is fine, but when you go to create the ostream function it can't match the template type to what you have for a class.

template <typename T>
ostream& operator <<(ostream& os, const PriorityQueue<T>& rhs)
{
...
}

Remember templates are made at compile time. When you create a PriorityQueue object (lets say int for arguments sake) then you made all the PriorityQueue::(insert function here) implementations. When you try and call ostream << PriorityQueue there was never a function created to handle that because at compile time there was no reason to call ostream operator<<(ostream&, PriorityQueue<T>).

To fix this, all you need to do is make the ostream function inside the class definition.

template <typename T>
class PriorityQueue : private List<T>
{
    ...
    friend ostream& operator <<(ostream& os, const PriorityQueue<T>& rhs)
    {
        ...
    }
}

Now each time you make a PriorityQueue object it will have its own ostream function. So a PriorityQueue<int> will have a ostream& operator <<(ostream&, const PriorityQueue<int>&) function and a PriorityQueue<std::string> will have a ostream& operator <<(ostream&, const PriorityQueue<std::string>&) function.

Mark Walsh
  • 985
  • 1
  • 7
  • 12