1

PREVIOUS PROBLEM FIXED AND UPDATED ARRAYQUEUE.CPP WITH CURRENT VERSION

                                 ***CURRENT PROBLEM***

I have gotten my items that I am enqueueing to correctly pop up in the my program but for some reason my queue is outputting the rear only.

Output:

 Item #0: 1


 Item #1: 2

  Here is the queue: 2

The resize function is used to double the size of the ArrayQueue if the capacity is exceeded and the capacity is halve the size of the array when an item is dequeued if it causes the number of items to be half the capacity or less

ArrayQueue.h:

#ifndef ARRAY_QUEUE_H
#define ARRAY_QUEUE_H

#include "QueueInterface.h"
#include "PrecondViolatedExcep.h"

template<class ItemType>
class ArrayQueue : public QueueInterface<ItemType>
{
public:
    ArrayQueue();
    ArrayQueue(const ArrayQueue& right);
    ArrayQueue operator =(const ArrayQueue& right);
    ~ArrayQueue();
    bool isEmpty() const;
    void enqueue(const ItemType& newEntry);
    void dequeue();
    ItemType peekFront() const;
    void print() const;
    int getSize();
private:
    static const int DEFAULT_CAPACITY = 1;
    ItemType* items;
    int front;
    int back;
    int numItems;
    int capacity;
    void resize(int);
};

#include "ArrayQueue.cpp"
#endif

ArrayQueue.cpp:

#include <iostream>

using namespace std;

template<class ItemType>
ArrayQueue<ItemType>::ArrayQueue() {
    front = 0;
    back = DEFAULT_CAPACITY - 1;
    numItems = 0;
    capacity = DEFAULT_CAPACITY;
    items = new ItemType[capacity];
}





template<class ItemType>
ArrayQueue<ItemType>::ArrayQueue(const ArrayQueue<ItemType>& right)
{
    numItems = right.numItems;
    items = new ItemType[strlen(right.items) + 1];
    strcpy(items, right.items);
}





template<class ItemType>
ArrayQueue<ItemType> ArrayQueue<ItemType>::operator =(const ArrayQueue& right)
{

    if (this != right)
    {
        numItems = right.numItems;
        delete[] items;
        items = new ItemType[right.capacity];
        strcpy(items, right.items);
    }
    return *this;
}






template<class ItemType>
ArrayQueue<ItemType>::~ArrayQueue()
{
    delete[] items;
}




template<class ItemType>
bool ArrayQueue<ItemType>::isEmpty() const {
    return numItems == 0;
}





template<class ItemType>
void ArrayQueue<ItemType>::enqueue(const ItemType& newEntry)
{
    //ItemType* temp = new ItemType;
    if (isEmpty()) {
        //front = back = 0;
        back = (back + 1) % capacity;
        items[back] = newEntry; //Problem *SOLVED FOR NOW*
        //items = temp;
        numItems++;
    }
    else
    {
        if (numItems == capacity)
        {
            resize(2 * capacity);

        }

        back = (back + 1) % capacity;
        //back = (back + 1) % capacity;

        if (back == capacity - 1)
            back = 0;

        items[back] = newEntry;
        //items = temp;
        numItems++;

    }
    std::cout << std::endl;

    std::cout << "Item #" << numItems - 1 << ": " << items[(numItems - 1) % capacity] << std::endl;
    std::cout << endl;

}


template<class ItemType>
int ArrayQueue<ItemType>::getSize()
{
    return capacity;
}


template<class ItemType>
void ArrayQueue<ItemType>::dequeue()
{
    std::cout << std::endl;
    std::cout << "Item Being removed: " << items[front] << std::endl;
    if (isEmpty())
    {
        throw PrecondViolatedExcep();
    }
    else
    {
        if (numItems == capacity / 2)
        {
            resize(capacity / 2);
        }
        if (back == front)
            back = front = 0;
        else
        {
            front = (front + 1) % capacity;
            numItems--;
        }
        std::cout << std::endl;
    }

    std::cout << "New item at front: " << items[front] << std::endl;
    std::cout << std::endl;
}




template<class ItemType>
ItemType ArrayQueue<ItemType>::peekFront() const
{
    if (isEmpty()) {
        throw PrecondViolatedExcep("peekFront() called with empty queue");
    }

    return items[front];
}





template<class ItemType>
void ArrayQueue<ItemType>::print() const {
    std::cout << "Here is the queue: ";
    if (isEmpty()) {
        std::cout << "empty";
    }
    else {
        for (int i = front; i != back; i = (i + 1) % capacity) {
            std::cout << items[i] << " ";
        }
        std::cout << items[back];
    }
}




template<class ItemType>
void ArrayQueue<ItemType>::resize(int newCapacity)
{

    ItemType* temp = new ItemType[newCapacity];
    for (int i = 0; i < capacity; i++)
    {
        int index = (front + i) % capacity;
        temp[i] = items[index];

    }
    front = 0;
    back = numItems - 1;
    delete[] items;
    items = temp;
    capacity = newCapacity;
}

QueueInterface.h:

#ifndef QUEUE_INTERFACE_
#define QUEUE_INTERFACE_

template<class ItemType>
class QueueInterface

{
public:
   /** Sees whether this queue is empty.
    @return True if the queue is empty, or false if not. */
   virtual bool isEmpty() const = 0;

   /** Adds a new entry to the back of this queue.
    @post If the operation was successful, newEntry is at the 
       back of the queue.
    @param newEntry  The object to be added as a new entry.
    @return True if the addition is successful or false if not. */
   virtual void enqueue(const ItemType& newEntry) = 0;

   /** Removes the front of this queue.
    @post If the operation was successful, the front of the queue 
       has been removed.
    @return True if the removal is successful or false if not. */
   virtual void dequeue() = 0;

   /** Returns the front of this queue.
    @pre The queue is not empty.
    @post The front of the queue has been returned, and the
       queue is unchanged.
    @return The front of the queue. */
   virtual ItemType peekFront() const = 0;

   /** Destroys object and frees memory allocated by object. */
   virtual ~QueueInterface() { }
}; // end QueueInterface
#endif

PrecondViolatedExcep.cpp:

#include "PrecondViolatedExcep.h"  

PrecondViolatedExcep::PrecondViolatedExcep(const std::string& message)
         : std::logic_error("Precondition Violated Exception: " + message)
{
} 

PrecondViolatedExcep.h:

#ifndef PRECOND_VIOLATED_EXCEP_H
#define PRECOND_VIOLATED_EXCEP_H

#include <stdexcept>
#include <string>


class PrecondViolatedExcep : public std::logic_error
{
    public:
       PrecondViolatedExcep(const std::string& message = "");
};
#endif

Client file used for testing Functions:

#include <iostream>
#include "ArrayQueue.h"
#include "PrecondViolatedExcep.h"
#include "QueueInterface.h"

using namespace std;

int main()
{   
    ArrayQueue<int> attempt;

    /*attempt.enqueue(6);
    attempt.enqueue(5);
    attempt.enqueue(4);
    attempt.enqueue(3);
    attempt.enqueue(2);  */

    attempt.enqueue(1);
    attempt.enqueue(2);
    attempt.enqueue(3);


    attempt.print();

    cout << "The capacity is " << attempt.getSize();
}
15
  • Check the documentation for strcpy. You'll find it's really only useful for copying null-terminated strings. Using it on anything else is fatal. The program right not crash right away, but it's only a matter of time. Commented Nov 14, 2020 at 3:31
  • #include "ArrayQueue.cpp" can also be a bad idea. Many build tools will see that cpp file and assume it needs to be compiled and linked. When it does, you'll get multiple definition linker errors. It also confuses people reading the code. Rename ArrayQueue.cpp to something harmless and associated with headers like ArrayQueue.hpp Commented Nov 14, 2020 at 3:40
  • The ArrayQueue constructor doesn't initialize items. Leaves the object in a risky condition. When you enqueue into an empty list, it's beyond empty. It doesn't exist. Kaboom. Commented Nov 14, 2020 at 4:02
  • @user4581301 Would I initialize it as items = new ItemType[DEFAULT_CAPCITY]? Commented Nov 14, 2020 at 4:27
  • @user4581301 I updated the constructor initialize items as stated above but get a very extraneous number such as -842023 instead of the one digit number I am attempting to enqueue Commented Nov 14, 2020 at 4:31

1 Answer 1

1

In this state of the code, I believe you have a problem with the Modulo operator (%).

You are using DEFAULT_CAPACITY in many places, which I think you intended to use capacity. Having a modulo 1 of any number should result in 0 everywhere, which means you are only copying/setting/keeping/saving the first and only value, and thus only one output.

back = (back + 1) % DEFAULT_CAPACITY;
items[back] = newEntry;
int index = (front + i) % DEFAULT_CAPACITY
temp[i] = items[index];
Sign up to request clarification or add additional context in comments.

1 Comment

Oh, I think I realized where I went wrong. I updated it to 50 and took your advice of not having it always be set to one and my queue actually updates now. Thank You!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.