Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this function cause a segfault?

I wrote the following simple function to perform modular exponentiation. However, it segfaults when the exponent parameter is greater than about 261,000. Why is this? And how can I fix it?

I'm compiling with gcc on 64-bit Ubuntu.

Thanks

unsigned int modex(unsigned int base, unsigned int exponent, unsigned int modulus)
{
   if(exponent == 1)
      return base;

   base = base % modulus;

   if(exponent == 0 || base == 1)
      return 1;

   return (modex(base, exponent - 1, modulus) * base) % modulus;
}
like image 440
Richard Avatar asked Feb 20 '26 21:02

Richard


2 Answers

@ouah already posted the answer in a comment, so if he wants to post an answer I'll delete this.

You have a stack overflow. You are recursing too many times and blowing your stack space. C++ does not guarantee tail call optimization (even if you didn't have that operation on the return value of the recursive call at the end), so you're better off implementing this using a loop.

If you want to stick with the recursive route, try making it truly tail recursive via the explanation here and see if the compiler helps you out.

like image 90
Ed S. Avatar answered Feb 22 '26 13:02

Ed S.


You're creating a enormous recursion chain. You should try to save memory and processing by doing it iterative.

unsigned modex(unsigned base, unsigned exponent, unsigned modulus){

    unsigned
        result = 1;

    while(expoent--){
        result *= base;
        result %= modulus;

    }

    return result;

}

Still, you can do it even faster.

like image 40
Rodrigo Siqueira Avatar answered Feb 22 '26 13:02

Rodrigo Siqueira