【问题标题】:Array Out Of Bounds Exception Cannot find [closed]数组越界异常找不到[关闭]
【发布时间】:2014-08-02 01:03:43
【问题描述】:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 110 

    at HeapPriorityQueue.hasLeft(HeapPriorityQueue.java:168)
    at HeapPriorityQueue.bubbleDown(HeapPriorityQueue.java:111)
    at HeapPriorityQueue.removeMin(HeapPriorityQueue.java:73)
    at a4tester.testRandomArray(a4tester.java:224)
    at a4tester.stressTest(a4tester.java:237)
    at a4tester.main(a4tester.java:283)

我一直在试图找出 Out of bounds 异常的来源,这让我发疯了!只有当我的 HeapPriorityQueue 通过下面的压力测试时才会出现。 当我的代码通过这个压力测试时,基本上得到一个数组越界异常:

public static boolean testRandomArray (int count) {

    PriorityQueue q = createNewPriorityQueue(count);

    System.out.println("Testing size: " + count);
    Random r = new Random();

    for ( int i = 0; i < count; i++ )
    {
        int val = r.nextInt(1000000);
        q.insert (val);
    }

    int oldVal = -1;

    while (!q.isEmpty() )
    {
        int val = (int)((Integer)q.removeMin()).intValue(); // or a bug

        if ( oldVal > val )
            return false;
        oldVal = val;
    }
    return true;

}

这是我的程序:

public class HeapPriorityQueue implements PriorityQueue {
protected final static int DEFAULT_SIZE = 10000;

/* This array is where you will store the elements in the heap */
protected Comparable storage[];

/* Keep track of the current number of elements in the heap */
protected int currentSize;

/* You do not need to change this constructor */
public HeapPriorityQueue () 
{
    this(DEFAULT_SIZE);
}

/* You do not need to change this constructor */
public HeapPriorityQueue(int size)
{
    storage = new Comparable[size + 1];
    currentSize = 0;
}

/*
 * You need to change the implementation of every public method
 * below this comment.
 *
 */
public int size () {
    return currentSize;
}

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

public Comparable removeMin () throws HeapEmptyException {
    if(isEmpty())
        throw new HeapEmptyException();
    Comparable returnValue = storage[1];
    storage[1] = storage[currentSize];
    storage[currentSize] = null;
    currentSize--;
    bubbleDown();
    return returnValue;
}

public void insert ( Comparable k  ) throws HeapFullException {
    if(currentSize >= storage.length - 1)
        throw new HeapFullException();
    currentSize++;
    storage[currentSize] = k;
    bubbleUp();

}

/* Your instructor's solution used the following helper methods
 * 
 * You do not need to use the same methods, but you may want to.
 */

/* 
 * A new value has just been added to the bottom of the heap
 * "bubble up" until it is in the correct position
 */
private void bubbleUp () {
    int index = currentSize;
    while(parent(index) != 0 && storage[parent(index)].compareTo(storage[index]) > 0) {
        swapElement(index, parent(index));
        index = parent(index);
    }
}

/*
 * Because of a removeMin operation, a value from the bottom
 * of the heap has been moved to the root.
 * 
 * "bubble down" until it is in the right position
 */
private void bubbleDown() {  
    int index = 1;   
    while (hasLeft(index)) {    
        int sc = leftChild(index);  
        if (hasRight(index) && storage[leftChild(index)].compareTo(storage[rightChild(index)]) > 0) {  
            sc = rightChild(index);  
        }   
        if (storage[index].compareTo(storage[sc]) > 0) {  
            swapElement(index, sc);  
        } 
        else{
        }
        index = sc;  
    }          
}

/*
 * Swap the element at position p1 in the array with the element at 
 * position p2
 */
private void swapElement ( int p1, int p2 ) {
    Comparable temp = storage[p1];
    storage[p1] = storage[p2];
    storage[p2] = temp;
}

/*
 * Return the index of the parent of the node at pos
 */
private int parent ( int pos )
{
    return (pos/2); // replace this with working code
}

/* 
 * Return the index of the left child of the node at pos
 */
private int leftChild ( int pos )
{
    return (pos*2); // replace this with working code
}

/* 
 * Return the index of the right child of the node at pos
 */
private int rightChild ( int pos )
{   
    return (pos * 2)+1; // replace this with working code
}

/*
 * Given the current number of elements in the heap, does the
 * node at pos have a left child?
 *
 * Note that all internal nodes have at least a left child.
 *
 */
private boolean hasLeft ( int pos )
{
    if(storage[leftChild(pos)] != null)
        return true;
    return false; // replace this with working code
}

/*
 * Given the current number of elements in the heap, does the
 * node at pos have a right child?
 */ 
private boolean hasRight ( int pos ) {
    if(storage[rightChild(pos)] != null)
        return true;
    return false; // replace this with working code
}

}

【问题讨论】:

  • 确保使用显示行号的编辑器。这样可以很容易地找到故障线路。
  • 那么,第 168 行是什么?错误发生在第 168 行。知道是哪一行,至少可以很容易地看到异常的原因。没有这些信息,你就会强迫读者猜测。

标签: java arrays bounds out


【解决方案1】:

有几件事可能存在问题:

private boolean hasLeft ( int pos )
{
    if(storage[leftChild(pos)] != null)
        return true;
    return false; // replace this with working code
}

应该改为:

private boolean hasLeft ( int pos )
{
    if (storage.length > leftChild(pos) && storage[leftChild(pos)] != null)
        return true;
    return false; // replace this with working code
}

因为您可能会超出原始代码的范围。同样的逻辑适用于hasRight()。此外,您还尝试访问storage,但您从不检查它的长度,即您有storage[1],但不能保证您没有将0 传递给您的构造函数。希望对您有所帮助。

【讨论】:

  • 是的,我只是注意到 hasLeft 不会检查左孩子的索引是否超出范围。这解决了一切。谢谢!
  • @Athind 没问题。由于您是 SO 新手,请查看tour
猜你喜欢
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-18
相关资源
最近更新 更多