简体   繁体   中英

Why am I getting Stack Overflow error in Recursive C program while computing elements of pascal triangle?

I am writing a C program to compute (i,j)th element in Pascular Triangle ie f(n,1) = f(n,n) = n, and f(n,k) = f(n-1,k) + f(n-1,k-1) for 1 < k < n I need to print value modulo 1000000007. The Code follows :

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

unsigned long int returnModPascal(unsigned long int n,unsigned long int k);

int main()
{
    int t;
    unsigned long int ans,n,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lu %lu",&n,&k);
        ans=returnModPascal(n,k);
        printf("%lu",ans);
    }

    return 0;
}

unsigned long int returnModPascal(unsigned long int n,unsigned long int k)
{
    unsigned long int tempans,tempans1,tempans2;
    if(k==1 || k==n)
        tempans=n;
    else
    {
        tempans1=returnModPascal(n-1,k);
        if (tempans1>=1000000007)
            tempans1=tempans1%1000000007;
        tempans2=returnModPascal(n-1,k-1);
        if (tempans2>=1000000007)
            tempans2=tempans2%1000000007;
        if (tempans1+tempans2>=1000000007)
            tempans=tempans1+tempans2-1000000007;
        else
            tempans=tempans1+tempans2;
    }

    return tempans;
}

When i give input for example 123456 3 as n & k ( It works fine with smaller integer values like 23 2 or 12 3 as n&k ) Error is coming

Unhandled exception at 0x003C3D79 in DummyProject.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x003D2F70).

Any Help is appreciated.

Since you made your returnModPascal function recursive, there must be space on the stack for each recursive call.

For example, if you read in 123456 , your call to returnModPascal will end up allocating a stack frame for n = 123456 , n = 123455 , n = 123454 , and so on. There's not nearly enough memory for that.

To fix this, you're going to have to rewrite your function so that you don't end up making this many recursive calls for the larger inputs.

The typical stack limits are in some 1000s of KBs. In linux you can use

ulimit -a

to know yours (mine is about 8 MB). Since unsigned long int can go up to (again, assuming gcc) 18446744073709551615 (in 64 bit) or 4294967295 (in 32 bit) [I maybe wrong, See your limits.h], and your one stack frame must be of size 2 words, a stack overflow is quite imminent.

I see you want an alternative. 我看到你想要一个替代方案。 Have you considered using combinatorics? "Calculate" (i,j)th entry by i C j . By that I mean don't actually find factorials and multiply, but cancel out all the terms you can (integral value will always appear) until only a sequence of integers (mathematical sense) remain. Use modular multiplication (mod 1000000007). Read up about efficient modular multiplication using generator exponents.

Look at this line of code:

tempans1=returnModPascal(n-1,k);

You call the recursive function at the very beginning, this means that the function will go till the very end of recursion chain before it gets any chance to further process the input. So if you call this function with a comparatively large input such as 123456 , this means that the function will have to "stacked" 12345 times before it finally gets to evaluate the if condition.

You should try reducing the input, or a better alternative is to call the function recursively after if statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM