This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Priamos7's profile picture

[Error] java.lang.ArrayIndexOutOfBoundsException: 256

Started by Priamos7, 09 April 2013 - 03:45 AM
Priamos7 #1
Posted 09 April 2013 - 05:45 AM
I made a little program tasking a turtle with harvesting my carrot fields, unfortunately i seem to have created a loop which crashes the turtle.

The exact error

turtle:13: vm error: java.lang.ArrayIndexOutOfBoundsException: 256

The program

x = 1
y = 1
dir = 1

function forward()
if (dir == 3) then
turtle.forward()
x = x - 1
elseif (dir == 1) then
turtle.forward()
x = x + 1
elseif (dir == 2) then
turtle.forward()
y = y + 1
elseif (dir == 4) then
turtle.forward()
y = y - 1
end
harvest()
end

function harvest()
turtle.digDown()
turtle.select(1)
turtle.placeDown()
check()
end

function turnleft()
turtle.turnLeft()
if dir == 4 then
dir = dir - 3
else
dir = dir + 1
end
end

function turn(orientation)
if dir ~= orientation then
repeat
turnleft()
until dir == orientation
end
end

function check()
if ((y == 4) or (y == 8) or (y == 12) or (y == 16)) and (dir == 2) then
forward()
elseif (x == 19) and (dir == 1) then
turn(2)
forward()
elseif (x == 19) and (dir == 2) then
turn(3)
harvest()
elseif (x == 1) and (dir == 3) then
turn(2)
forward()
elseif (x == 1) and (dir == 2) then
turn(1)
harvest()
elseif (y == 20) then
finish()
elseif turtle.getItemCount(15) == 64 then
deload()
else
forward()
end
end

function finish()
print("done")
turn(3)
repeat
turtle.forward()
x = x - 1
until x == -2
turn(4)
repeat
turtle.forward()
y = y - 1
until y == 1
drop()
turn(1)
repeat
turtle.forward()
x = x + 1
until x == 1
os.reboot()
end
function drop()
i = 1
for i = 1,16 do
turtle.select(i)
turtle.dropDown()
end
turtle.select(1)
end

function deload()
ysave = y
xsave = x
dirsave = dir
turn(3)
repeat
turtle.forward()
x = x - 1
until x == -2
turn(4)
repeat
turtle.forward()
y = y - 1
until y == 1
drop()
turn(2)
repeat
turtle.forward()
y = y + 1
until y == ysave
turn(1)
repeat
turtle.forward()
x = x + 1
until x == xsave
turn(dirsave)
forward()
end

harvest()

It would also be great if u could help me shorten this line:

if ((y == 4) or (y == 8) or (y == 12) or (y == 16)) and (dir == 2) then

Thanks for your time.
theoriginalbit #2
Posted 09 April 2013 - 06:01 AM
Ok I'm looking into the problem now, following all your function calls through.

However as for your second question there isn't really any other way to make it smaller except for doing this

if ((y >= 4) and (y <= 16) and (y % 4 == 0) and (dir == 2) then
this makes sure its between 4 and 16 and is a multiple of 4.


EDIT: Ok, so in your function check. which is called from harvest, you then call harvest again in two of the if conditions. then in other conditions you call harvest from forward.
This constant calling of the functions from other ones is quickly filling up the programs stack.
What I suggest you do to fix it is to make harvest use a while loop, with a conditional that has….. *needs to check*…… y ~= 20, then have the finish function called after the for loop… then remove all the function calls to harvest and this should fix the problem, unless I'm missing another problem.
Edited on 09 April 2013 - 04:07 AM
Priamos7 #3
Posted 09 April 2013 - 06:53 AM
Hm I usually call functions like this and never met this error but maybe this is new in 1.5
Thank you anyway :)/>
Ill try the while loop, though I dont really like looping with while
Izodn #4
Posted 09 April 2013 - 08:01 AM
My untrained eyes suggest that your issue is from lines 96 and 97

turtle.select(1)
end
end is called without having a function/statement to end.
Engineer #5
Posted 09 April 2013 - 11:40 AM
My untrained eyes suggest that your issue is from lines 96 and 97

turtle.select(1)
end
end is called without having a function/statement to end.
It does have a purpose, the end is closing the function.
Maybe you got confuser because the code wasnt indented, or you didnt know that you needed to close a function.

Good try though :P/>
theoriginalbit #6
Posted 09 April 2013 - 04:48 PM
Hm I usually call functions like this and never met this error but maybe this is new in 1.5
Thank you anyway :)/>
Ill try the while loop, though I dont really like looping with while
No it's not new in 1.5, this error is actually common to most people. And it has been in every version of CC and Lua and every other programming language in the world. Chances are, the reason you have never encountered this before, is that your programs never run for long enough, or call enough functions to fill the stack. Basically using recursion (calling a function to create a loop) is always a bad idea and should never be a replacement for a while, repeat, or for loop. ever!
xuanlongLP #7
Posted 30 April 2013 - 10:50 PM
There's no reason to be hating on recursion, especially when Lua supports tail call optimization. All you need to do is add a 'return' before your tail call functions and you won't get a stack overflow.

Here's the harvest function with the fix:

function harvest()
  turtle.digDown()
  turtle.select(1)
  turtle.placeDown()
  return check()
end

and here's a more complicated example, check():

function check()
  if ((y == 4) or (y == 8) or (y == 12) or (y == 16)) and (dir == 2) then
    return forward()
  elseif (x == 19) and (dir == 1) then
    turn(2)
    return forward()
  elseif (x == 19) and (dir == 2) then
    turn(3)
    return harvest()
  elseif (x == 1) and (dir == 3) then
    turn(2)
    return forward()
  elseif (x == 1) and (dir == 2) then
    turn(1)
    return harvest()
  elseif (y == 20) then
    return finish()
  elseif turtle.getItemCount(15) == 64 then
    return deload()
  else
    return forward()
  end
end

You need a return for each function call at the end of an if block since there's nothing after the if structure to come back into the function for. So the function calls at the end of the if blocks are all exit points for the function.
theoriginalbit #8
Posted 01 May 2013 - 12:24 AM
-snip-
Valid point, which I personally know about and understand… Unfortunately most users here are either young, or not programmers so do not understand concepts such as these, so as such we state that recursion is bad, and there are only a few key times to use it. most people whole use it on these forums get the stack overflow error and come here for help.