Phaneeth
Phaneeth

Reputation: 305

priority queue, why is it still printing the last element

This is my first time working with queue's and dequeue's. The concept is simple but I am having a problem when I am trying to use STL.

#include <iostream>
#include <string.h>
#include <queue>
#include <ctime>
#include <stdlib.h>

using namespace std;

int main(){
    srand(time(NULL));
    priority_queue<int> pq;
    for(int i = 0; i < 10; i++){
        int t = rand() % 100;
        cout << "Pushing " << t << " on top of queue." << endl;  
        pq.push(t);
    }
    while(!pq.empty()){
        cout << pq.top() << " : is on top of queue " << endl;
        pq.pop();   
    }

    if(pq.empty()){
        cout << pq.top() << endl;
        cout << "list is empty" << endl;    
    }
    pq.pop();
    cout << pq.top() << endl;
    return 0;   
}

I wanted to see what is printed if the queue is empty but when I do that it always prints the last element.My output looks like this.

Pushing 58 on top of queue.
Pushing 89 on top of queue.
Pushing 76 on top of queue.
Pushing 38 on top of queue.
Pushing 21 on top of queue.
Pushing 69 on top of queue.
Pushing 25 on top of queue.
Pushing 49 on top of queue.
Pushing 58 on top of queue.
Pushing 59 on top of queue.
89 : is on top of queue 
76 : is on top of queue 
69 : is on top of queue 
59 : is on top of queue 
58 : is on top of queue 
58 : is on top of queue 
49 : is on top of queue 
38 : is on top of queue 
25 : is on top of queue 
21 : is on top of queue 
21
list is empty
21

Can anyone tell me why this is happening. Why it is printing 21 even when the list is completely empty. From my intuition the last element is stored somewhere in the buffer, if the queue is empty and if one tries to access the empty queue this element is printed out.

Upvotes: 2

Views: 621

Answers (2)

Richard Hodges
Richard Hodges

Reputation: 69864

Try it again with this small modification:

#include <iostream>
#include <cstring>
#include <queue>
#include <ctime>
#include <cstdlib>
#include <memory>

using namespace std;

struct Foo
{
    Foo(int x) : p(std::make_unique<int>(x)) {}
    std::unique_ptr<int> p;
};

std::ostream& operator<<(std::ostream& os, const Foo& f)
{
    return os << *f.p;
}

bool operator<(const Foo& l,const Foo& r)
{
    return *(l.p) < *(r.p);
}


int main()
{
    srand(time(NULL));
    priority_queue<Foo> pq;
    for(int i = 0; i < 10; i++){
        auto t = Foo(rand() % 100);
        cout << "Pushing " << t << " on top of queue." << endl;
        pq.push(std::move(t));
    }
    while(!pq.empty()){
        cout << pq.top() << " : is on top of queue " << endl;
        pq.pop();
    }

    if(pq.empty()){
        cout << pq.top() << endl;
        cout << "list is empty" << endl;
    }
    pq.pop();
    cout << pq.top() << endl;
    return 0;
}

Then let's have a discussion about Undefined Behaviour.

Upvotes: 0

top can only be called on a non-empty queue. Calling it when the queue is empty causes Undefined Behaviour, meaning anything can happen.

Upvotes: 5

Related Questions