/* Recursion.c * Stephanie Taylor and Ying Li * Demonstrate what happens when we try to recurse too much */ #include #include #include // This illustrates that we run out of stack space and that generates // a SEGV (segmentation fault) // With smaller arrays on the stack (i.e. smaller stack frames), we get more // levels of recursion (before the SEGV) // With larger arrays on the stack (i.e. larger stack frames), we get fewer // levels of recursion (before the SEGV) // Adjusting the amount of space we use on the heap does not affect the // depth of recursion. // If we ask for too much space on the heap, malloc returns 0x0 // but no signal is sent, so we wouldn't observe an error // unless we were to try to use the pointer. // Years ago, it died because it was killed. SRT can't find a computer/compiler that // will reproduce that in Fall 2023 (not that she checked too many places) // Without the heap allocation, it gets killed // stack 0x75f553af2f58, heap (nil) // Killed #define STACK_ARRAY_LEN 100000 // #define STACK_ARRAY_LEN 10 // #define STACK_ARRAY_LEN 1 // #define HEAP_ARRAY_LEN 1000000000 // #define HEAP_ARRAY_LEN 100000 #define HEAP_ARRAY_LEN 1 void recurse( long long unsigned n ) { int i = 0; i++; int b[STACK_ARRAY_LEN]; // SRT put this code here to give the variable a value, to make sure // the optimizer didn't optimize it away. It turns out that code wasn't // necessary, so it has been commented out. // for (i = 0; i < STACK_ARRAY_LEN; i++) { // b[i] = 2; // } // memset( b, 2, STACK_ARRAY_LEN*sizeof(int) ); int *a = (int *)malloc( HEAP_ARRAY_LEN * sizeof(int) ); if (n % 10 == 0) { printf( "n = %llu, stack %p, heap %p\n", n, &a, a ); } if (n == 0) { printf( "n = %llu\n", n ); return; } recurse( n-1 ); } int main() { recurse( 1000000000 ); return 0; }