views:

17509

answers:

7

I'm a complete beginner writing Breakout (the game) in Java. All was going well until I started to get a stack overflow error in the late game. Unfortunately I know that without actually putting the code up online I won't really be able to get help with this. So instead I thought I would make this my first Stackoverflow.com question!

What is a "stack overflow" error, what causes it and how do real programmers deal with them?

Thanks a lot!

(oh, I'm using the acm libraries (I think), if that's any help?)

A: 

Like you say, you need to show some code. :-)

A stack overflow error usually happens when your function calls nest too deeply. See the Stack Overflow Code Golf thread for some examples of how this happens (though in the case of that question, the answers intentionally cause stack overflow).

Chris Jester-Young
I would totally like to add code, but as I don't know what causes stack overflows I am not sure what code to add. adding all the code would be lame, no?
Ziggy
Is your project open-source? If so, just make a Sourceforge or github account, and upload all your code there. :-)
Chris Jester-Young
this sounds like a great idea, but I am such a noob that I don't even know what I would have to upload. Like, the library that I am importing classes that I am extending etc... are all unknowns to me. Oh man: bad times.
Ziggy
+2  A: 

A stack overflow is usually called by nesting function calls too deeply (especially easy when using recursion, i.e. a function that calls itself) or allocating a large amount of memory on the stack where using the heap would be more appropriate.

Greg
Java doesn't provide the means to allocate structures or arrays on the stack, so the second part of your answer doesn't apply; otherwise, great answer. :-)
Chris Jester-Young
Oops, didn't see the Java tag
Greg
Also, from the original poster here: nesting functions too deeply in what? Other functions? And: how does one allocate memory to the stack or heap (since, you know, I've clearly done one of these things without knowing).
Ziggy
@Ziggy: Yes, if one function calls another function, which calls yet another function, and so on, after many levels, your program will have a stack overflow. [continues]
Chris Jester-Young
[...continued] In Java, you can't directly allocate memory from the stack (whereas in C, you can, and this would then be something to watch for), so that's unlikely to be the cause. In Java, all direct allocations come from the heap, by using "new".
Chris Jester-Young
+5  A: 

If you have a function like:

int foo()
{
    // more stuff
    foo();
}

Then foo() will keep calling itself, getting deeper and deeper, and when the space used to keep track of what functions you're in is filled up, you get the stack overflow error.

Khoth
Wrong. Your function is tail-recursive. Most compiled languages have tail-recursion optimizations. This means the recursion reduces into a simple loop and you will never hit stack overflow with this piece of code on some systems.
Cheery
not in java though.
Chii
Cheery, which non-functional languages support tail recursion?
banister
C, C++, Python (with unladen swallow)...
Clark Gaebel
@wowus +1 for holy grail
Cyclone
+3  A: 

All these answers are good, but this is a real stack overflow error

moogs
Hahahahahaha :-)
Quantenmechaniker
+19  A: 

Parameters and local variables are allocated on the stack (with reference types the object lives on the heap and a variable references that object). The stack typically lives at the upper end of your address space and as it is used up it heads towards the bottom of the address space (ie towards zero).

Your process also has a heap, which lives at the bottom end of your process. As you allocate memory this heap can grow towards the upper end of your address space. As you can see, there is the potential for the heap to "collide" with the stack (a bit like techtonic plates!!!).

The common cause for a stack overflow is a bad recursive call. Typically this is caused when your recursive functions doesn't have the correct termination condition, so it ends up calling itself for ever. However, with gui programming it's possible to generate indirect recursion. For example, your app may be handling paint messages and whilst processing them it may call a function that causes the system to send another paint message. Here you've not explicitly called yourself, but the OS/VM has done it for you.

To deal with them you'll need to examine your code. If you've got functions that call themselves then check that you've got a terminating condition. If you have then check than when calling the function you have at least modified one of the arguments, otherwise there'll be no visible change for the recusivly called function and the terminating condition is useless.

If you've got no obvious recursive functions then check to see if you're calling any library functions that indirectly will cause your function to be called (like the implicit case above).

Sean
Original poster: hey this is great. So recursion is always responsible for stack overflows? Or can other things be responsible for them as well?Unfortunately I am using a library... but not one that I understand.
Ziggy
Ha ha ha, so here it is: while (points < 100) {addMouseListeners(); moveball(); checkforcollision(); pause(speed);} Wow do I feel lame for not realizing that I would end up with a stackfull of mouse listeners... Thanks guys!
Ziggy
No, stack overflows can also come from variables being too big to allocate on the stack if you look up the Wikipedia article on it at http://en.wikipedia.org/wiki/Stack_overflow .
JB King
A: 

The most common cause of stack overflows is excessively deep or infinite recursion. If this is your problem, this tutorial about Java Recursion could help understand the problem.

splattne
+1  A: 

Stack overflow means exactly that: a stack overflows. Usually there's a one stack in the program that contains local-scope variables and addresses where to return when execution of a routine ends. That stack tends to be a fixed memory range somewhere in the memory, therefore it's limited how much it can contain values.

If the stack is empty you can't pop, if you do you'll get stack underflow error.

If the stack is full you can't push, if you do you'll get stack overflow error.

So stack overflow appears where you allocate too much into the stack. For instance, in the mentioned recursion.

Some implementations optimize out some forms of recursions. Tail recursion in particular. Tail recursive routines are form of routines where the recursive call appears as a final thing what the routine does. Such routine call gets simply reduced into a jump.

Some implementations go so far as implement their own stacks for recursion, therefore they allow the recursion to continue until the system runs out of memory.

Easiest thing you could try would be to increase your stack size if you can. If you can't do that though, the second best thing would be to look whether there's something that clearly causes the stack overflow. Try it by printing something before and after the call into routine. This helps you to find out the failing routine.

Cheery