Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any hard-wired limit on recursion depth in C

The program under discussion attempts to compute sum-of-first-n-natural-numbers using recursion. I know this can be done using a simple formula n*(n+1)/2 but the idea here is to use recursion.

The program is as follows:

#include <stdio.h>

unsigned long int add(unsigned long int n)
{
    return (n == 0) ? 0 : n + add(n-1); 
}

int main()
{
    printf("result : %lu \n", add(1000000));
    return 0;
}

The program worked well for n = 100,000 but when the value of n was increased to 1,000,000 it resulted in a Segmentation fault (core dumped)

The following was taken from the gdb message.

Program received signal SIGSEGV, Segmentation fault.
0x00000000004004cc in add (n=Cannot access memory at address 0x7fffff7feff8
) at k.c:4

My question(s):

  1. Is there any hard-wired limit on recursion depth in C? or does the recursion depth depends on the available stack memory?

  2. What are the possible reasons why a program would receive a reSIGSEGV signal?

like image 718
Sangeeth Saravanaraj Avatar asked Apr 20 '12 08:04

Sangeeth Saravanaraj


Video Answer


1 Answers

Generally the limit will be the size of the stack. Each time you call a function, a certain amount of stack is eaten (usually dependent on the function). The eaten amount is the stack frame, and it is recovered when the function returns. The stack size is almost almost fixed when the program starts, either from being specified by the operating system (and often adjustable there), or even being hardcoded in the program.

  • Some implementations may have a technique where they can allocate new stack segments at run time. But in general, they don't.

  • Some functions will consume stack in slightly more unpredictable ways, such as when they allocate a variable-length array there.

  • Some functions may be compiled to use tail-calls in a way that will preserve stack space. Sometimes you can rewrite your function so that all calls (Such as to itself) happen as the last thing it does, and expect your compiler to optimise it.

It's not that easy to see exactly how much stack space is needed for each call to a function, and it will be subject to the optimisation level of the compiler. A cheap way to do that in your case would be to print &n each time its called; n will likely be on the stack (especially since the progam needs to take its address -- otherwise it could be in a register), and the distance between successive locations of it will indicate the size of the stack frame.

like image 103
Edmund Avatar answered Oct 06 '22 12:10

Edmund