3

I have the following recursion method. I get an error stack overflow. it stops at -9352. My questions, is stack overflow the same as an infinite loop? Because this will keep calling itself.

But if I do a infinite loop with while, until, do, etc it doesn't give me the same stack overflow error. It just keeps going until my system runs out of memory.

This is using Ruby

def recursion(n)
    print n
    recursion(n-1)
end

recursion(3)

output:

3
2
1
0
.
.
.
-9352  stack overflow stops
hken27
  • 413
  • 1
  • 5
  • 12

1 Answers1

-1

Recursion and looping are techniques that can solve similar problems in different ways (as mentioned in the comments, they are Turing equivalent, but this is not my field).

Each function call adds a frame to the call stack. This requires additional memory and as your call chain goes deeper, it requires more memory until a certain limit is crossed, which makes your stack overflow and your program to crash.

Your recursive code adds more and more frames to the call stack and, given finite amount of memory, will cause it to overflow. You need some way to tell the recursion when to stop, and do so before the memory is exhausted. Such condition is equivalent to the base case in the mathematical induction, therefore it is usually referred to as such.

Another option, pointed in the comments, is utilizing Tail call optimizations, which replace the current frame in the stack and therefore may prevent the stack from overflowing.

Your iterative solution only requires a fixed amount of memory.

Only the value of a counter or other predefined variables is changed, therefore it does not incur any memory overhead.

If you do not limit the output, it could theoretically go on indefinitely, but some other exhaustion or error will most likely kill it. However, this will not be the memory consumed by the variables used in the loop itself.

MasterAM
  • 16,283
  • 6
  • 45
  • 66
  • 1
    Recursion and Iteration are not fundamentally different, as recursion is turing equivalent to a while loop. Also, the implication that the point at which stack overflow occurs is some fundamental constant is somewhere between misleading and incorrect. Also your entire post is totally incorrect if you consider tail-call optimized recursion which violates your basic principal. – Slater Victoroff Sep 01 '13 at 00:09
  • While I do agree with you on the subject of Turing equivalence (although I admittedly do not have deep knowledge in that, this is no my research area) , I tried to keep the answer simple and handle the specific case. I do not consider any compiler optimizations or edge cases, as I only wanted to illustrate the need for a base case in his example. As to the stack bound, AFAIK, it is determined during compile time or during the program start. I will edit my answer to reflect your comment, feel free to edit it or post your own answer. – MasterAM Sep 01 '13 at 00:25
  • Tail call optimization is far from an edge case, used in most functional languages, and all gcc compiled languages. You may be thinking of process memory, which is defined before program start or compile time. Stack size is a portion of the process memory depending on how much memory is currently allocated to the stack versus the heap. The heap memory changes as the program executes, so for many languages it is categorically impossible to determine available stack space. There's also a different between posting a simple answer and posting a deeply incorrect one. – Slater Victoroff Sep 01 '13 at 00:33
  • Thanks, @SlaterTyranus, didn't know this one. Good to know. Always happy to learn new stuff. – MasterAM Sep 01 '13 at 00:51