views:

188

answers:

2

Why do I get a segmentation fault in my recursive function. It happens every time i call it when a value greater than 4 as a parameter

#include <iostream>
#include <limits>

using namespace std;    

int printSeries(int n){
    if(n==1){       
        return 1;
    }
    else if( n==2){     
        return 2;
    }
    else if( n==3){
        return 3;
    }
    else if( n==4){
        return printSeries(1) + printSeries(2) + printSeries(3);
    }
    else{       
        return printSeries(n-3) + printSeries((n-2) + printSeries(n-1));
    }
}


int main(){

        //double infinity = numeric_limits<double>::max();

        for(int i=1; i<=10; i++){
            cout << printSeries(i) << endl;
        }

    return 0;

}

This works fine, but i'm not sure that returns the correct result:

return printSeries(n-3) + printSeries(n-2) + printSeries(n-1);
+17  A: 
return printSeries(n-3) + printSeries( (n-2) + printSeries(n-1) );
//                                     ^^^^^^^^^^^^^^^^^^^^^^^^

Incorrect nesting of parenthesis causes infinite recursion, which leads to stack overflow (segfault).

Consider when n = 4,

f(4) = 1 + f(2 + f(3))
     = 1 + f(2 + 3)
     = 1 + f(5)
     = 1 + [ f(2) + f(3 + f(4)) ]
     = ...
KennyTM
Shouldn't that throw an exception?
the_drow
@the_drow: Why should it throw an exception?
KennyTM
@the_drow: Why? It's perfectly valid, it just causes infinite recursion.
Rich Adams
@the_drow: Unfortunately, there's no `std::programmer_error` in C++. You might want to propose it, though.
sbi
I meant a stackoverflow exception
the_drow
@the_drow: There's no exception for that in C++. Well, at least not necessarily. A run-time environment is certainly allowed to throw an exception for that, but it's just as allowed to format your hard disk. A segmentation fault is a common outcome on Unix-like operating systems.
sbi
+4  A: 

The parentheses problem mentioned above is the source of the infinite recursion. But there's another problem with the code even if you fix the parentheses for case 5 to be like case 4:

printSeries(4) recursively invokes printSeries 3 times.
printSeries(5) recursively invokes printSeries 6 times.
printSeries(6) recursively invokes printSeries 12 times.
printSeries(10) recursively invokes printSeries 156 times.
printSeries(20) recursively invokes printSeries 69747 times.
printSeries(50) recursively invokes printSeries over 6 trillion times.

In other words, your code is doing way more work than it should. Do you see why?

Owen S.
Yeah, he needs to read about *memoization*.
Ben Voigt