Jack
Jack

Reputation: 2625

Avoiding index out of bounds exceptions

I am using an Array List to store data about moving objects on screen. I suspect this is because my renderer and my logic are running on separate threads, but sometimes when data is removed from the list I get an indexOutOfBoundsException. I have taken all the steps I can think of to avoid this including try/catch but the exception still sometimes occurs. This is the part of my renderer thread that seems to cause the exception.

public void drawMobs(GL10 gl) {
    boolean playing = MyLaunchActivity.getPlaying();
    if(playing == true){
        try{
             ArrayList<String> mobDat = Play.getMobDat();

        while (currentLoadSpace < mobDat.size()){

        if(!mobDat.isEmpty() || currentLoadSpace < mobDat.size()){

        loadObject = mobDat.get(currentLoadSpace);
        float loadCoordX = Float.parseFloat(mobDat.get(currentLoadSpace + 2));
        float loadCoordY = Float.parseFloat(mobDat.get(currentLoadSpace + 3));

        /*some rendering*/

        currentLoadSpace+=4;
            }
        }
}catch( ArrayIndexOutOfBoundsException e){ Log.d(TAG, "caught");}

    currentLoadSpace = 0;

}}

as you can see I have tried a few things but the error still occurs. Here is the error log

01-02 14:02:42.650: E/AndroidRuntime(6947): FATAL EXCEPTION: GLThread 10
01-02 14:02:42.650: E/AndroidRuntime(6947): java.lang.IndexOutOfBoundsException: Invalid index 23, size is 20
01-02 14:02:42.650: E/AndroidRuntime(6947):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at java.util.ArrayList.get(ArrayList.java:308)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at basicmelon.games.agameofsorts.LoadLevel.drawMobs(LoadLevel.java:530)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at basicmelon.games.agameofsorts.MyGLSurfaceRenderer.onDrawFrame(MyGLSurfaceRenderer.java:82)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1429)
01-02 14:02:42.650: E/AndroidRuntime(6947):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1184)

Upvotes: 1

Views: 24962

Answers (6)

Darksaint2014
Darksaint2014

Reputation: 172

I know there is already an answer, but try simply catching an IndexOutOfBoundsException instead of an ArrayIndexOutOfBoundsException

I suggest this because you`re catching the Array exception and still getting the standard Index exception. This is most likely due to the fact that Index is a "higher/lower" (however you want to see it) exception than the Array exception. Meaning that you did indeed catch the Array exception, but beyond that the Index one is still being thrown.

Upvotes: 0

Juha Laiho
Juha Laiho

Reputation: 596

Note also that you're checking that currentLoadSpace is smaller than mobDat.size(), but you're trying to retrieve from currentLoadSpace+3 (which, as far as this piece of code is concerned, may well be out of bounds).

Upvotes: 0

Sunil Kumar Sahoo
Sunil Kumar Sahoo

Reputation: 53667

You need to check for the arraylist size. The removed postion should not be greater than size oflist

You need to do somthing like the following

void avoidArrayIndexOutOfBounds(int position, ArrayList listOfdata){
        if(position>(listOfdata.size()-1)){

            position = listOfdata.size()-1;
        }

    }

Upvotes: 0

Adel Boutros
Adel Boutros

Reputation: 10295

Your code is inconsistent and is rather faulty. For example why do you test twice the same condition? (currentLoadSpace < mobDat.size())

Secondly, your error is coming from :

mobDat.get(currentLoadSpace + 3)

You're searching for index of 23 when mobDat only contains 21 elements. So you should check that the following lines are actually less than mobDat.size():

currentLoadSpace + 2

and

currentLoadSpace + 3

Upvotes: 2

Konstantin Pribluda
Konstantin Pribluda

Reputation: 12367

One possible solution could be:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

If this is not an option, you could use synchronized(yourList) {} to prevent concurent modifications.

Upvotes: 1

Tobias Bre&#223;ler
Tobias Bre&#223;ler

Reputation: 316

I think you have to synchronize the access to your ArrayList. ArrayList is not thread safe. To catch the IndexOutOfBoundsException is bad design. This exception should be avoided by your code.

Upvotes: 0

Related Questions