奇怪的数组索引越界异常
Posted
技术标签:
【中文标题】奇怪的数组索引越界异常【英文标题】:Weird array index out of bounds exception 【发布时间】:2014-07-07 11:45:10 【问题描述】:我的应用中有一些奇怪的东西我无法理解。
我正在实现一种算法,该算法检测何时产生脉冲响应(当强度值高于 0,2 时),当检测到它时,它会在脉冲刺激之前存储 0.5 秒的样本,并脉冲后的 1.5 秒。 在我检测到脉冲之前,所有样本都存储在 0.5 秒长的环形缓冲区中,当我产生脉冲时,下一个样本存储在 2 秒长的正常数组中,让一些空间稍后复制 0 ,5 秒的环形缓冲区样本。
问题是代码有时工作得很好,而其他时候它给了我数组索引超出范围的异常,如下所示:
07-07 13:31:47.312: E/androidRuntime(28823): java.lang.ArrayIndexOutOfBoundsException: length=16384; index=16384
07-07 13:31:47.312: E/AndroidRuntime(28823): at com.example.acoustics.GrabaAudio.calculateImpulseLevel(GrabaAudio.java:174)
我真的不知道在我的代码中哪里可以产生这个超出数组范围的异常,所以这就是我不明白的。 缓冲区大小为 8192。
private byte[] calculateImpulseLevel(byte[] array)
byte[] circBuffer=new byte[bufferSize*2];
for (int i=0; i<=array.length-3 ;i+=2)
double sampleAmpl=(double)Math.abs((array[i+1] << 8 | array[i] & 0xff)/32767.0);
if (sampleAmpl<0.2 && !triggered)
int s=circ.size();
if (s<circCapacity)
circ.add(array[i]);
circ.add(array[i+1]);
else
circ.remove(0);
circ.add(array[i]);
circ.remove(0);
circ.add(array[i+1]);
else
if(!triggered)
triggered=true;
indice = indice2+(bufferSize/2);//Empieza a poner en el array a partir de 0,5 seg de muestras
circBuffer[indice]=array[i];
circBuffer[indice+1]=array[i+1];
indice2+=2;
//if (indice >=((2*bufferSize)-3))
if (indice2 >=((3*bufferSize)/2)-3)
i=array.length-2;
System.arraycopy(toByteArray(circ),0,circBuffer,
0,circ.size());
//circ.removeAll(circ);
return circBuffer;
由于这个错误只会发生几次,而且通常情况下,当我第一次编译我的应用程序设备时,它工作得很好,而且我运行我的应用程序越多,它就会变得越来越糟,我认为这可能是由存储在使用后未正确擦除的变量。
你们觉得呢?
好的,我对代码做了一些修改,已经解决了索引数组越界异常的问题。
这是我更改的代码:
if(!triggered)
triggered=true;
indice=indice2+(bufferSize/2);
if (indice>2*bufferSize-2)
i=array.length;
else
circBuffer[indice]=array[i];
circBuffer[indice+1]=array[i+1];
indice2+=2;
/*if (indice >=2*bufferSize-3)
i=array.length;
*/
现在我遇到了一个新问题,当我在调试器模式下运行我的应用程序时,一切正常,但是,当我尝试在我的设备上正常运行它时,获得的音频数组显示为重复,它检测到脉冲响应总是在0,20 aprox 及其在 1,20 aprox 的重复版本,如下图所示:
(来源:subirimagenes.com)
这是我在调试器模式下得到的,实际上是我期望得到的:
(来源:subirimagenes.com)
为什么会这样?为什么只是在正常模式而不是在调试器中?
【问题讨论】:
GrabaAudio.java
的第 174 行是什么?
circBuffer[indice]=array[i];
我知道这一点。问题是我编码它的方式,显然这种情况不应该发生,但它确实发生了,我不知道我错过了什么。
length=16384; index=16384
索引应该是 16383。
indice2 只是一个初始化为 0 的局部变量。它将上升到 ((3*bufferSize)/2)-3 以确保我不会到达数组越界异常
【参考方案1】:
for (int i=0; i<=array.length-3 ;i+=2)
假设 array.lenght 是 100,那么最后一个索引是 99。那么条件就是 i<=97
。
最后一次迭代的 i=96。并且将使用的数组的最高索引是:97,在边界内。
根据您提供的数据,变量的Indice
max used index 为:
((3*bufferSize)/2)-3+(bufferSize/2)
等于2*bufferSize - 3
这比它的界限低 2 (bufferSize*2)。
一切似乎都井井有条。 Indice2 可能不是您让我们认为的那样。您可能想尝试将 bufferSize 设置为多 1 个字节,即byte[] circBuffer=new byte[bufferSize*2+1];
因为 16384 就是 8192*2。
【讨论】:
以上是关于奇怪的数组索引越界异常的主要内容,如果未能解决你的问题,请参考以下文章