-2

I am implementing a queue using a circular array. I cannot figure out what is causing my array out of bounds exception. I clearly know what the error means etc, it is indicating that my array got out of range and in my case, an index of -1. I clearly know what the error means but I do not why I am getting it in my case. Here is the run-time exception I get:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at Queue.dequeue(Queue.java:56)
at Queue.main(Queue.java:72)

And here is my queue implementation:

public class Queue<T>{
private int head, tail, size, capacity;
private T[] container;
private static final int DEFAULT_CAPACITY = 100;



public Queue(int n){
    capacity = n;
    head = -1;
    tail = -1;
    size = 0;
    container = (T[]) new Object[capacity];
}


public Queue(){
    this(DEFAULT_CAPACITY);
}

public boolean isEmpty(){
    return size == 0;
}

public boolean isFull(){
    return size == capacity;
}

public void enqueue(T item){
    if(isFull()){
        System.out.println("Queue Oveflow");
    }
    else{
        tail = (tail + 1) % (capacity - 1);
        size++;
        container[tail] = item;
    }
}

public T dequeue(){
    if(isEmpty()){
        System.out.println("Queue underflow");
        System.exit(1);
        return null;
    }
    else {
        if(head == tail){
            T item = container[head];
            head = -1;
            tail = -1;
            size --;
            return item;

        }
        else{
            T item = container[head];
            head = (head + 1) % (capacity -1);
            size --;
            return item;
        }
    }
}


public static void main(String[] args){
    Queue myQueue = new Queue();
    myQueue.enqueue(34);
    myQueue.enqueue(38);
    myQueue.enqueue(34);
    System.out.println(myQueue.dequeue()); 
}
}
codigomonstruo
  • 951
  • 1
  • 9
  • 39
  • Possible duplicate of [What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?](http://stackoverflow.com/questions/5554734/what-causes-a-java-lang-arrayindexoutofboundsexception-and-how-do-i-prevent-it) – John3136 Oct 27 '16 at 22:32
  • enqueue never changes the value of `head` – Tibrogargan Oct 27 '16 at 22:32
  • Possible duplicate of [What is a stack trace, and how can I use it to debug my application errors?](http://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors) – shmosel Oct 27 '16 at 22:35
  • Not a duplicate. I clearly know what an ArrayOutOfBounds exception means. I just do not why I am getting it in this case. Stop marking duplicates before you read the question carefully. – codigomonstruo Oct 27 '16 at 22:41
  • @Tibrogargan have you seen anywhere in my code where enqueue is changing the value of head ? Can you point it out for me ? – codigomonstruo Oct 27 '16 at 22:43
  • 2
    @MoussaSarr No I have not, that's exactly the problem. `head` starts as `-1` and you never change it. `-1` is not a valid array index, so when `dequeue` tries to do this: `T item = container[head]` (which evaluates to `T item = container[-1]` it throws an exception. Since the only operation you do between the constructor and the `dequeue` is `enqueue` I assume that's where `head` is supposed to get modified. Less defensiveness please, people here are trying to help. – Tibrogargan Oct 27 '16 at 22:47
  • Right that makes sense. Thanks @Tibrogargan – codigomonstruo Oct 27 '16 at 22:48
  • @shmosel I don't think that post is meant to be a duplicate target. – OneCricketeer Oct 27 '16 at 22:51
  • @cricket_007 Yeah, probably not :) – shmosel Oct 27 '16 at 22:52
  • @MoussaSarr If you already know what an ArrayOutOfBoundsException means, then you know exactly why you're getting it in this case: because you're trying to access an invalid array index. If you want to know *how* that came about, well that's what debugging is for. This site is meant to help people with *specific* questions; it's not a substitute for debugging. – shmosel Oct 27 '16 at 22:57
  • thanks. @Tibrogargan, thanks it works now. I added a case in enqueue for when the queue is empty. – codigomonstruo Oct 27 '16 at 22:58
  • @shmosel, says who ? A debugging question is a programming question too. A huge percentage of questions asked here are what you call "debugging questions" What do you think is the reason why people post their code ? – codigomonstruo Oct 27 '16 at 23:02
  • A question about debugging? Perhaps. A question that could be solved by debugging instead of expecting other people to put in the work for you? It may *technically* be a programming question, but it's a lousy one that's not likely to garner much interest. See [here](http://stackoverflow.com/help/how-to-ask) and [here](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) for more info. – shmosel Oct 27 '16 at 23:09
  • Yes, unfortunately a huge percentage of people people ask questions that could be solved with some basic debugging skills. And there's a big difference between a code **post** and a code **dump**. The former is a specific piece of code pertaining to a specific question. The latter is a product of laziness and entitlement, expecting others to do your own work for you. – shmosel Oct 27 '16 at 23:14
  • @shmosel haha lol you almost got me there. In my case I was extremely tired and low energy that I could not see why the array is out of bounds . And that s right, at least 90% of questions asked here can be solved through debugging and I cannot see anywhere it says you cannot ask such questions. But sometimes also, just because it's a debugging question does not mean that you can solve it. Sometimes debugging it right might require some additional knowledge you do not posses and it will take the good people of stackoverflow to make you realize that missing piece of information you needed – codigomonstruo Oct 27 '16 at 23:19

2 Answers2

1

Circular buffers are confusing, to me at least, but when you call dequeue, value of head is still -1 because that is what you initialize it to. With a circular buffer I believe you would want to initialize the "head" or "read" position to some valid point in the array - doesn't really matter which index. Instead you are initializing it to an invalid index into the array. The head pointer then gets updated if a wrap-around occurs and it is over-written. Definitely use a debugger. https://en.wikipedia.org/wiki/Circular_buffer

Jim Weaver
  • 883
  • 4
  • 13
1

Changing the enqueue method to this solved the problem :

   public void enqueue(T item){
    if(isFull()){
        System.out.println("Queue Oveflow");
    }
    else if(isEmpty()){
        head = 0;
        tail = 0;
        container[tail] = item;
        size++;

    }
    else{
        tail = (tail + 1) % (capacity - 1);
        size++;
        container[tail] = item;
    }
}
codigomonstruo
  • 951
  • 1
  • 9
  • 39