【问题标题】:ArrayIndexOutOfBoundsException with legal index , java, imagejArrayIndexOutOfBoundsException 与合法索引,java,imagej
【发布时间】:2013-01-17 09:01:20
【问题描述】:

我目前正试图让我的头脑围绕 imagej,并试图复制图像并吐出输出。总体思路是获取图像,从图像处理器中获取像素阵列,将其复制到新阵列中,然后从该阵列构建新图像。

现在,aPixels_org[0] 的值存在,您可以从控制台输出中看到。但即使我进行了所有检查,它仍然会引发 arrayoutofbounds 异常。

这是代码...(顺便说一句。只是一个记录器对象,只是一个健全性检查以检查数组值是否存在于下面的 if 条件中。请告知是否有更好的方法,就像我一样一个 c++ 人,习惯于直接检查东西,因为 java 不允许 if(int){} 检查)

我从一个函数中获取 aPixels_org,aPixels_dup 就是这样创建的

int[] aPixels_dup = new int[iWidth*iHeight];

其中 iWidth*iHeight 是所需数组的大小。我还尝试使用 array.length() 选项直接生成大小。 问题代码是

System.out.println(">>>>>>>>>>>>>>>>>>>>>." + aPixels_dup[0] +"  " + aPixels_org[0] + "  " + iWidth + "  " + iHeight);
    if(Integer.toString(aPixels_org[0]) != null &&  Integer.toString(aPixels_dup[0]) != null )
    {
        l.info("Arrays exsist");
        System.arraycopy(aPixels_org,0,aPixels_dup,0,iWidth*iHeight);
        l.info("Array Copied");
    }
    else{l.warn("Something is NULL");}
    l.info("");

这是错误

java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at Alpha_.DuplicateCurrentImage(Alpha_.java:64)
at Alpha_.run(Alpha_.java:81)
at ij.IJ.runUserPlugIn(IJ.java:185)
at ij.IJ.runPlugIn(IJ.java:152)
at ij.Executer.runCommand(Executer.java:127)
at ij.Executer.run(Executer.java:64)
at java.lang.Thread.run(Thread.java:679)

这是控制台输出

[INFO] % FILE: Alpha_.java % CLASS: Alpha_ % FUNCTION: DuplicateCurrentImage % LINE: 59    % COMMENT: OK % % % TIMESTAMP: 2013-01-17 00:26:55,942
 0  -1393202  466  466
[INFO] % FILE: Alpha_.java % CLASS: Alpha_ % FUNCTION: DuplicateCurrentImage % LINE: 63 % COMMENT: Arrays exsist % % % TIMESTAMP: 2013-01-17 00:26:55,942

我的输出到此结束,程序因上述错误而崩溃。如您所见,所有 4 个值都以某种形式存在。我google了一下错误,发现错误是

抛出以指示已使用非法索引访问了数组。索引为负数或大于等于数组的大小。

我在这里遗漏了什么明显的东西吗?

重新

【问题讨论】:

  • 这是一个很好的练习,可以让你做更复杂的事情,但如果你想做的只是创建一个图像的副本调用'ImageProcessor.duplicate()'

标签: java imagej


【解决方案1】:

两个数组 —aPixels_orgaPixels_dup — 的长度必须至少为 iWidth*iHeight(根据您的控制台输出为 217156)。一个(或两个)数组必须比那个短,这就是你得到异常的原因。还要确保iWidth*iHeight 的值在分配aPixels_dup 和调用System.arraycopy 之间没有增加。

使用Math.min(aPixels_org.length, aPixels_dup.length) 作为System.arraycopy 的最后一个参数会更安全。但是,这会隐藏代码中的任何长度错误。您可能希望assert 两个数组都具有预期的长度。

此外,您的支票似乎毫无意义。两个数组中都存在索引 0 处的元素这一事实有点无关紧要。此外,Integer.toString(int) 永远不会返回 null。这是您的代码的一个版本,可以进行一些合理的检查:

if (aPixels_org != null &&
    aPixels_dup != null &&
    aPixels_org.length == aPixels_dup.length &&
    aPixels_org.length == iWidth*iHeight )
{
    l.info("Array sizes match");
    System.arraycopy(aPixels_org,0,aPixels_dup,0,iWidth*iHeight);
    l.info("Array Copied");
}
else{l.warn("Something is NULL or dimensions are off");}
l.info("");

【讨论】:

  • Dup 已分配 - 必须是源数组太短
  • @Bohemian - 除非iWidthiHeight 的值在分配和调用System.arraycopy 之间上升。
  • 图像是否有多个帧?如果是这样,您应该将 iWidthiHeightiNoOfFrames 用于数组长度
  • @medPhys-pl - 好点。实际上,为了复制数据,只使用数组长度就足够了,忽略iWidthiHeight的值。
【解决方案2】:

全部在JavaDoc强调了我认为是你错误的原因。

 public static void arraycopy(Object src,
             int srcPos,
             Object dest,
             int destPos,
             int length)
 ...

否则,如果以下任一情况为真,则抛出 IndexOutOfBoundsException 且不修改目标:

  • srcPos 参数是否定的。
  • destPos 参数是否定的。
  • length 参数是否定的。
  • srcPos+length 大于源数组的长度src.length
  • destPos+length 大于目标数组的长度 dest.length

【讨论】:

    猜你喜欢
    • 2021-05-10
    • 2014-05-11
    • 2014-03-23
    • 1970-01-01
    • 2011-09-05
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多