-2

What are the ways to overflow stack, using recursion? I have a such way

#include <iostream>

void func()
{
    int arr[100500];
    func();
}

int main()
{
    func();

    std :: cin.ignore(); std :: cin.get();

    return 0;
}

But I don't like it.

Yahia
  • 69,653
  • 9
  • 115
  • 144
Andrew
  • 261
  • 3
  • 16

3 Answers3

3

It's remarkably easy to fill the stack up due to infinite recursion;

void func() { func(); }

will do it well enough. Any function call pushes information onto the stack (at least a return address), and so if it doesn't stop calling itself at some point, it'll run out of available stack.

I find it hard to see why you would dislike such a function as you have shown as an example of doing it. It does what is needed and it does it fast.

However, it is possible that optimisation will cause the compiler to turn the function into an infinite loop, as it is easy to spot it doesn't do anything.

If you want a demonstration of a function that actually does something,

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

is a good example, given a suitably large value of n, and no compiler optimisation (or it might spot the opportunity for tail recursion and turn that into a loop as well).

Failing that, try this (Ackermann's function, an example of a recursive function that is not primitively recursive and is also not going to be subject to optimisation in the last line.

unsigned int A(unsigned int m, unsigned int n)
{
    if (m == 0) return n + 1;
    if (n == 0) return A(m - 1, 1);
    return A(m - 1, A(m, n - 1));
} 

Exercise for the reader: Given an intelligent compiler, how much optimisation can be applied to minimise the recursion.

Tom Tanner
  • 9,244
  • 3
  • 33
  • 61
0

In main() you call func() which then calls func() (itself) which then calls func() (itself) etc.

Every time a function is called, pointers are pushed onto the stack. The stack is a limited amount of memory and will eventually fill and then you get a stack overflow.

Since your program will call func() endlessly the stack will quickly fill.

Note also that the local variable arr will also be allocated on the stack. This will more quickly fill up the stack.

Sani Huttunen
  • 23,620
  • 6
  • 72
  • 79
  • I know it :) But, when i was testing(in MSVC++ 2010), there were no signs that stack was full... – Andrew Feb 09 '12 at 07:52
  • 3
    You're not incurring a stack overflow because the compiler will optimize the recursion away, turning it into a simple loop, in this case. What you've written there is called a tail recursive function; tail recursion is a simple case that can almost always be optimized into a loop. – aalpern Feb 09 '12 at 08:04
0

When recursion is too deep ot can cause stack overflow since function local variables and return addresses are stored on the stack. In your case you have infinite recursion, that is, you don't have a condition to stop func() from calling itself, and thus you're overflowing the stack.

There's no defined limit, and it depends on language and architecture you run recursion over.

m0skit0
  • 25,268
  • 11
  • 79
  • 127
  • You may want to read the answers to this question, http://stackoverflow.com/questions/2630054/does-c-limit-recursion-depth. The C++ language does not define a limit on stack depth. Your operating system, on the other hand, will enforce a limit on the amount of space the stack can occupy. – aalpern Feb 09 '12 at 07:59
  • @LuchianGrigore Where do you find this defined lower limit? I've never seen it nor heard about it, and I can't find it in the standard. (Of course, finding something in the standard isn't always trivial.) – James Kanze Feb 09 '12 at 08:23
  • @JamesKanze I'm looking for it :). But it has to be there?... right? If it isn't, crashing after even the first recursive call would be standard compliant... – Luchian Grigore Feb 09 '12 at 08:32
  • Thinking about it, I don't think it's in the standard. That IMHO is architecture dependant and C++ cannot go in there... And yes, crashing even in the first recursive call *can* be standard compilant. – m0skit0 Feb 09 '12 at 08:53
  • 1
    @LuchianGrigore Crashing after the first function call (recursive or not) is compliant. In practice, in certain extreme cases, it can even happen, at least under Linux or Solaris: the stack on entering `main` is right at a page boundary, and there are no more available pages in swap space. (Actually, it's possible that Linux and/or Solaris guarantee a minimum amount of stack before starting the process. But you get the idea.) Historically, "insufficient resources" was undefined behavior (but I can't find where it says that in the current standard). – James Kanze Feb 09 '12 at 09:15