简体   繁体   中英

Can anyone explain why does this recursive function crash?

Why does this recursive (i'm not sure about it, the site i found this code said it was "recursive") code crash (i found this weird approach on Inte.net, but i'm honestly not understanding how it works) entering values >4000 (sometimes >4023, sometimes >4015, i really don't understand...)...

#include <iostream>
unsigned long long int sum(unsigned long long int k)
{
    if (k > 0) {
        return k + sum(k - 1);
    }
    else {
        return 0;
    }
}
int main()
{
    unsigned long long int n;
    std::cout << "This program prints the sum of the first N natural numbers.\n\
Enter N: _";
    std::cin >> n;
    std::cout << "The sum is: " << sum(n) << ".\n\
Press any key to exit...";
    system("pause>nul");
    return 0;
}

while this, instead, does not?

#include <iostream>
int main()
{
    unsigned int n;
    std::cout << "Questo programma stampa la somma dei primi N numeri naturali.\n\
Prego inserire N: _";
    std::cin >> n;
    unsigned long long int tmp = 0;
    for (n; n != 0; --n) {
        tmp += n;
        //std::cout << tmp << ' ';
    }
    std::cout << "La somma \212: " << tmp << ".\n\
Premere un tasto per uscire...";
    system("pause>nul");
    return 0;
}

The recursive version uses a little bit of stack space every time it calls itself, so it is limited by the size of the stack and will crash if it calls itself too many times. It's a classic stack overflow error.

The iterative second version doesn't have that problem.

Your first approach

The first approach is recursive. That means that it calls the function sum() once for each k. Lets say, k is 2, than sum() is called twice and so on.

Each function call requires space on the stack for its parameters, local variables and some management data like the stack pointer, the return address to which the program jumps when the function returns and some other stuff. When you call sum() too often, lets say some 4000 times there is not enough space on the stack left for the very next call to sum(). In result you get a stack overflow and your application crashes.

The exact maximum of k you could provide until your app crashes depends on your system. That means, on a desktop with Windows, Linux or MacOS with a "big" stack you can call the function with k = round about 4000 times while on an embedded system the stack per thread may be lower, and your application crashes earlier.

Your second approach

Your second approach is not recursive and therefore does not require any additional space on the stack for calls to other functions. Therefore your application does not crash since you do not get the stack overflow from the first approach.

In addition, your second approach should run much faster since you do not require the time for the many function calls.

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