Search code examples
c++queueradix

C++ std::deque pop_front() not removing elements from queue


I'm implementing a simple radix sort for a school report and using a std::deque in my implementation of the intermediate bucket sort. The problem is that when I perform a pop_front(), the front element is not removed. I tired to work around this with clear() and empty(itr) operation, but the data in the queue is not removed in both cases. I've verified that the data is not being removed from the queue in all 3 cases with GDB. This messed up the entire sort because the elements from each digit sort end up in queue's, then into the sorted list.

The way I've gotten around this is to reallocate all ten queue's each iteration of the digitCount for loop. But that adds overhead that should not have to be there.

The Integer class is just a wrapper over a list of digits in each number and numerical representation of that number.

What am I doing wrong that's causing the elements to not pop off of the queue?

void SerialRadix::radixSort(){

    //todo: add support for numbers of varying lengths

    std::vector<std::deque<Integer> > buckets;
    //populate m_buckets with queues
    for (int j = 0; j < 10; j++){

        std::deque<Integer> bucket;
        buckets.push_back(bucket);
    }

    const int digitCount = m_integers[0].getDigitCount();
    int digitValue; //used in loop

    // look at all digits in each number. 'i' is the digit location. digits in ascending order, loop in reverse
    for (int i = digitCount - 1; i >= 0; i--){

        // loop over all numbers in list
        for (Integer numToSort : m_integers){

            digitValue = numToSort.m_digits[i];

            //place number in bucket based on digit value
            buckets[digitValue].push_back(numToSort);
        }

        int index = 0;

        // empty buckets back into sorted list
        for (std::deque<Integer> bucket : buckets){

            while (!bucket.empty()){
                m_integers[index] = bucket.front();
                bucket.pop_front(); //!problem is here! not removing from queue

                // if this is last digit to sort, place into sorted list when pulled from bucket
                if (!i){
                    m_sortedList[index] = m_integers[index].getNumber();
                }

                index++;
            }
        }
    }
}

Solution

  • for (std::deque<Integer> bucket : buckets){
    

    Your bucket of type std::deque<Integer> is being passed by value in the for loop.

    for (std::deque<Integer>& bucket : buckets){
    

    Just pass a reference to the bucket deque instead.


    Explanation:

    When we pass an object by value, a copy of the object is created and any changes made to that copy will not affect the original object. To actually change or affect the original object we pass an object by reference.

    In your code, object of type std::deque<Integer> is being passed by value in the for loop. It creates a copy in your bucket variable, and any changes made to bucket will only reflect in the copy only not the original in your buckets vector.

    Using the & operator you can pass the std::deque<Integer> object by reference. This will create a reference to your original deque in the buckets vector and any changes made to bucket will be reflected in the original deque.