8

Can you give an example of stack overflow in C++?

Jason
  • 36,170
  • 5
  • 26
  • 60
Nadir SOUALEM
  • 3,451
  • 2
  • 23
  • 30

12 Answers12

23

The typical case that does not involve infinite recursion is declaring an automatic variable on the stack that is too large. For example:

int foo()
{
    int array[1000000];

}
Tall Jeff
  • 9,834
  • 7
  • 44
  • 61
11

Please see Stack overflow - Wikipedia. I have linked directly to the examples section.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
8
void function() 
{
    function();
}
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
John Boker
  • 82,559
  • 17
  • 97
  • 130
  • 1
    +1 clean and straightforward. This is ALL you need to blow the stack. – Paul Sasik Nov 01 '09 at 16:01
  • 1
    Can we make it shorter? Yes, we can! `void _(){_();}` ... it's almost like Perl ;) – Thomas Nov 01 '09 at 16:08
  • 1
    The difference is, in Perl land, it's more likely that you'll blow *your* stack before Perl does. – Rob Nov 01 '09 at 16:09
  • 2
    Since this function takes no arguments, declares nothing, and returns nothing, I wonder if a smart optimizer might simple turn this into an infinite loop, in which case, it would not blow the stack... – dicroce Nov 01 '09 at 17:33
6

Here's one that might happen in practice:

int factorial(int x) {
  return x == 0 ? 1 : x * factorial(x-1);
}

This overflows the stack for negative x. And, as Frank Krueger mentioned, also for too large x (but then int would overflow first).

Community
  • 1
  • 1
Thomas
  • 174,939
  • 50
  • 355
  • 478
3

Keep trying to return main until the stack runs out?

int main(int argc, char **argv)
{
    return main(argc, argv);
}
Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
  • 3
    It's not legal to call main() in C++. – Tmdean Nov 01 '09 at 16:46
  • I know it won't format correctly, but there's no warnings with `-Wall` even for this more proper program: int main(int argc, char **argv) { if (argc == 0){return 0;} else {std::cout << argc << std::endl; return main(0, argv);} } – Mark Rushakoff Nov 01 '09 at 17:41
  • I mean it's odd that `g++` doesn't give any warnings when you call main; you are indeed correct (from what I've seen) that the standard disallows calling `main`. – Mark Rushakoff Nov 01 '09 at 17:45
  • @Mark Rushakoff: g++ does give an error if you compile with the `-pedantic` flag, although in my case it gives the somewhat incorrect error of `ISO C++ forbids taking address of function '::main'` – Adam Rosenfield Nov 01 '09 at 18:45
3

As per edit :-)

void ping()
{
    pong();
}

void pong()
{
    ping();
}

Also, I believe you can get stack overflow if you try to allocate more space than maximum thread stack size ( 1MB by default in VS), so something like int a[100000]; should provide the exception.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Naveen
  • 74,600
  • 47
  • 176
  • 233
3

Compile-time example:

template <int N>
struct Factorial {
    enum { value = N * Factorial<N - 1>::value };
};

// ...
{
    int overflow = Factorial<10>::value;
}
wilhelmtell
  • 57,473
  • 20
  • 96
  • 131
2

I can't believe we left off the greatest recursion example of all time, factorial!

#include <stdio.h>

double fact(double n) {
    if (n <= 0) return 1;
    else return n * fact(n - 1);
}

int main() {
    printf("fact(5) = %g\n", fact(5));
    printf("fact(10) = %g\n", fact(10));
    printf("fact(100) = %g\n", fact(100));
    printf("fact(1000) = %g\n", fact(1000));
    printf("fact(1000000) = %g\n", fact(1000000));
}

On OS X 10.5.8 with GCC 4.0.1:

$ gcc f.c -o f && ./f
fact(5) = 120
fact(10) = 3.6288e+06
fact(100) = 9.33262e+157
fact(1000) = inf
Segmentation fault

Unfortunately, OS X reports a "Segmentation fault" instead of a "Stack overflow". Too bad.

Frank Krueger
  • 69,552
  • 46
  • 163
  • 208
1

This example shows uncontrolled recursion. Eventually, the stack spaced allocated to this process will be completely overwritten by instances of bar and ret...

int foo( int bar )
{
    int ret = foo( 42 );
    return ret;
}
dicroce
  • 45,396
  • 28
  • 101
  • 140
1

If you want to generate an explicitly non-recursive program to result in a stack overflow by function calls:

#!/usr/bin/env python
import sys

print "void func" + sys.argv[1] + "() { }"
for i in xrange(int(sys.argv[1])-1, -1, -1):
    print "void func" + str(i) + "() { func" + str(i+1) + "(); }"
print "int main() { func0(); return 0; }"

Sample output:

$ python recursion.py 5
void func5() { }
void func4() { func5(); }
void func3() { func4(); }
void func2() { func3(); }
void func1() { func2(); }
void func0() { func1(); }
int main() { func0(); return 0; }

Sample usage:

$ python recursion.py 250000 | g++ -x c++ - && ./a.out

At least on my system, the call stack seems to be 174602, so you'll need to set the argument to recursion.py to be larger than that; and it takes a few minutes to compile and link the program.

Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
0

Infinite recursion:

void infiniteFunction()
{
    infiniteFunction();
}

int main()
{
    infiniteFunction();
    return 0;
}
Krzysztof Bujniewicz
  • 2,407
  • 21
  • 16
0

You could also get a stack overflow if you try to put large objects on the stack (by-value).

EricSchaefer
  • 25,272
  • 21
  • 67
  • 103