Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code cause a stack overflow?

Tags:

ruby

recursion

The following would cause stack overflow for large 'n', and I can understand why.

def factorial(n)
  (n > 1) ? (return (n * factorial(n - 1))) : (return 1)
end

Why does the following cause overflow as well?

def factorial(n, k)
  (n > 1) ? (return factorial(n - 1, lambda {|v| return k.call(v * n)})) : (return k.call(1))
end
like image 400
g06lin Avatar asked Apr 17 '09 19:04

g06lin


People also ask

What is a stack overflow error and how can it happen C++?

A stack overflow error can occur in a computer program due to excessive memory usage. This excessive memory usage occurs on the call stack, which is where information is stored relating to the active subroutines in the program. The call stack has a limited amount of memory available to it.

What causes stack overflow error in Java?

StackOverflowError is a runtime error which points to serious problems that cannot be caught by an application. The java. lang. StackOverflowError indicates that the application stack is exhausted and is usually caused by deep or infinite recursion.

What is the cause of the stackoverflow exception?

StackOverflowException is thrown for execution stack overflow errors, typically in case of a very deep or unbounded recursion. So make sure your code doesn't have an infinite loop or infinite recursion. StackOverflowException uses the HRESULT COR_E_STACKOVERFLOW, which has the value 0x800703E9.


3 Answers

Your second algorithm creates a n-long chain of lambda procedures, each containing a reference to the previous one. I don't know exactly what Ruby does, but in a properly tail-recursive language the stack would not overflow in your second algorithm, because k.call in the lambda is also in tail position. If, as Brian's experiment suggests, Ruby doesn't have proper tail calls, the n-long chain of nested calls to the lambda will overflow the stack when the head of the chain is invoked, even though Ruby is smart enough to convert the tail-recursive factorial call into a loop (= tail-call optimisation).

like image 154
Anton Tykhyy Avatar answered Sep 28 '22 00:09

Anton Tykhyy


In most languages, function calls go onto the call stack, which is really just the stack. Calling a function recursively keeps adding to the call stack. Eventually you fill up the stack, and you get a stack overflow. That's always a danger when running a recursive function where your recursion level is going to be deep.

like image 39
Brad Barker Avatar answered Sep 28 '22 02:09

Brad Barker


For the same reason the first one has a stack overflow... The callstack gets too large.

like image 42
Matt Grande Avatar answered Sep 28 '22 02:09

Matt Grande