Java System.arraycopy()引发越界异常
我基于数组创建了一个通用的调整大小的循环缓冲区,它在我的测试中做得很好,直到这个特殊情况发生时Java System.arraycopy()引发越界异常,java,generics,data-structures,indexoutofboundsexception,Java,Generics,Data Structures,Indexoutofboundsexception,我基于数组创建了一个通用的调整大小的循环缓冲区,它在我的测试中做得很好,直到这个特殊情况发生时 头=尾和 整个数组由元素填充 我希望数组能像往常一样调整大小,将head=0,tail=插入的新位置,一切正常。但这就是我得到的输出: adding : e head : 5 tail : 5 , size : 12 a b c d e f g h i j k l adding : f resizing array to size: 24 Exception in thread "main" ja
adding : e
head : 5 tail : 5 , size : 12
a b c d e f g h i j k l
adding : f
resizing array to size: 24
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at ResizingCircularArray.resize(ResizingCircularArray.java:16)
at ResizingCircularArray.enqueue(ResizingCircularArray.java:33)
at ResizingCircularArray.main(ResizingCircularArray.java:105)
可能是一些微小但重要的事情,但我似乎找不到可能是什么。有人能帮忙吗
注意:head>下一次出列的位置
尾部>下一个排队位置 编辑:根据ns47731的建议,我将我的arraycopy行从
system.arraycopy(arr,head,tempArr,0,size)更改为:代码>到系统数组复制(arr,0,tempArr,0,size)代码>。这虽然解决了异常问题,但会导致逻辑错误,如下所示:
43.dequeing : f
head : 13 tail : 20 , size : 7
null null null null null null null null null null null null null g h i j k l m null null null null
44.dequeing : g
resizing array to size: 12
head : 0 tail : 6 , size : 6
null null null null null null null null null null null null
也就是说,数据部分ghijklm
正在被删除
我意识到问题出在System.arraycopy()本身,它是为线性阵列而不是圆形阵列设计的,因此我为自己创建了一个简单的版本,可以用于圆形阵列:
private void arrayCopy(E[] srcArr , int srcpos , E[] destArr , int destpos , int length){
for(int index = 0 ; index < length ; index++){
destArr[index] = srcArr[head++];
if(head == srcArr.length){
head = (head % srcArr.length);
}
}
}
使您的阵列副本为只读
System.arraycopy(arr, 0, tempArr, 0, size);
为什么??参数#2(int)startPos是它应该从源数组开始复制的位置,您从数组的长度开始,导致索引超出范围
有关该方法的更多详细信息,请参阅
编辑:首先,我解决了您的初始问题,您应该自己解决其余问题。。阅读ArrayCopyJavadoc(顺便说一句,它写得非常好)。它应该是System.arraycopy(arr,head,tempArr,0,tail head) @SomjitNag我复制了你的代码和文本文件并运行了它,对我来说效果很好。我编辑了我之前的评论,因为虽然你的回答解决了引发的异常,但它产生了一个不同的问题。我正在更新我的帖子以反映这一点。我认为System.arraycopy不适用于循环数组,所以为我自己创建了一个可以使用循环数组的版本。我已经相应地更新了我的帖子和代码。ps:稍后我必须将异常部分添加到我的arrayCopy()版本中。您是否尝试将其更改为System.arrayCopy(arr,head,tempArr,0,tail head);这样做有什么好处tail-head
似乎不是一种获得圆形数组大小的简单方法。不过我可能错了。`if(tail==arr.length){//绕tail=(tail%arr.length);}`这是没用的。如果要实际检查相等性,则可以说tail=0
。如果您使用tail=tail%arr.length
则根本不需要使用If语句,当tail小于arr.length时,tail不会改变。您是对的。我留着它告诉自己我在做什么。如果这有道理的话。一旦最终测试完成,我会删除它。
enq a;enq b;enq c;enq d;enq e;enq f;enq g;enq h;enq i;enq j;enq k;enq l;deq;deq;deq;deq;deq;enq a;enq b;enq c;enq d;enq e;enq f;enq g;enq h;enq i;enq j;enq k;enq l;enq m;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;disp;stop
System.arraycopy(arr, 0, tempArr, 0, size);