Я делаю некоторые обходные пути, чтобы в полной мере воспользоваться удобством Eclipse. Ниже я нашел то, что у меня получилось. Надеюсь, что это поможет:
Типичный случай, не связанный с бесконечной рекурсией, - это объявление слишком большой автоматической переменной в стеке. Например:
int foo()
{
int array[1000000];
}
Вы также можете получить переполнение стека, если попытаетесь поместить в стек большие объекты (по значению).
Если вы хотите сгенерировать явно нерекурсивную программу, чтобы вызвать переполнение стека вызовами функций:
#!/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; }"
Пример вывода:
$ 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; }
Пример использования:
$ python recursion.py 250000 | g++ -x c++ - && ./a.out
По крайней мере, в моей системе стек вызовов выглядит как 174602, поэтому вам нужно установить аргумент recursion.py
, чтобы он был больше этого; и для компиляции и компоновки программы требуется несколько минут.
Я не могу поверить, что мы остановились на величайшем примере рекурсии всех времен, факториале!
#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));
}
В OS X 10.5.8 с 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
К сожалению, OS X сообщает «Ошибка сегментации» вместо «Переполнение стека». Жаль.
Пример времени компиляции:
template <int N>
struct Factorial {
enum { value = N * Factorial<N - 1>::value };
};
// ...
{
int overflow = Factorial<10>::value;
}
Бесконечная рекурсия:
void infiniteFunction() { infiniteFunction(); } int main() { infiniteFunction(); return 0; }
В этом примере показана неконтролируемая рекурсия. В конце концов, стек, выделенный для этого процесса, будет полностью перезаписан экземплярами bar и ret ...
int foo( int bar )
{
int ret = foo( 42 );
return ret;
}
Продолжать попытки вернуть main, пока стек не закончится?
int main(int argc, char **argv)
{
return main(argc, argv);
}
Вот что может произойти на практике:
int factorial(int x) {
return x == 0 ? 1 : x * factorial(x-1);
}
Это переполняет стек для отрицательных x
. И, , как упомянул Франк Крюгер , также для слишком большого x
(но тогда int
переполнится первым).
См. Переполнение стека - Википедия . Я связался напрямую с разделом примеров.
Согласно редактированию: -)
void ping()
{
pong();
}
void pong()
{
ping();
}
Кроме того, я считаю, что вы можете получить переполнение стека, если попытаетесь выделить больше места, чем максимальный размер стека потока (1 МБ по умолчанию в VS), поэтому что-то например int a [100000];
должен обеспечивать исключение.