0

I am getting a weird array index out of bound exception when I use the length of the array as the index

I have twice checked everything and printed some stuff like the array.length to the console

Here is the problematic code

public static boolean doJumpSearch(int array[], int number) {

           int start = 0;
           int end = (int) Math.sqrt(array.length); 



           while(array[end] <= number && end < array.length) {
              start = end; 
              end += (int)Math.sqrt(array.length);
              if(end > array.length - 1)
                 end = array.length; 
           }

           for(int i = start; i<end; i++) { 
              if(array[i] == number)
                 return true; 
           }
           return false;

    } 

Here is the runner code

public static void main(String[] args) {

        int[] a = {1, 2, 3};



        if(search.doJumpSearch(a, 3)) System.out.println("Yup");

    }

Here is the error

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
    at Rector.array.search.doJumpSearch(search.java:46)
    at dummy.main(dummy.java:12)
Wizard28
  • 355
  • 1
  • 3
  • 12
  • Did you trace step by step the code? The error is thrown here: `if(array[i] == number)` because `i` is greater than 2. – forpas Jul 22 '19 at 11:59

2 Answers2

3

The statement marked by // 1 followed by the statement marked by // 2 will cause the exception:

       while(array[end] <= number && end < array.length) { // 2
          start = end; 
          end += (int)Math.sqrt(array.length);
          if(end > array.length - 1)
             end = array.length;  // 1
       }

You should probably change the loop's condition to:

while(end < array.length && array[end] <= number)

to take advantage of the short circuit behavior of && (i.e. only evaluate array[end] if end < array.length is true).

Eran
  • 387,369
  • 54
  • 702
  • 768
1

Array elements go from 0 to array.length - 1. So array[end] will give an exception if end >= array.length.

In your method, this can happen in two scenarios:

  • when you assign array.length to end
  • when you calculate end to be (int) Math.sqrt(array.length), and array.length is 1.

Now you are checking that end < array.length in the while condition, but unfortunately you check after evaluating the subexpression that does the indexing.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216