Pouvez-vous donner un exemple de débordement de pile en C++? Autre que le cas récursif:Pouvez-vous donner un exemple de débordement de pile en C++?
void foo() { foo(); }
Pouvez-vous donner un exemple de débordement de pile en C++? Autre que le cas récursif:Pouvez-vous donner un exemple de débordement de pile en C++?
void foo() { foo(); }
Le cas typique qui n'implique pas la récursion infinie est la déclaration d'une variable automatique sur la pile qui est trop grande. Par exemple:
int foo()
{
int array[1000000];
}
Veuillez vous reporter à Stack overflow - Wikipedia. J'ai lié directement à la section des exemples.
void function()
{
function();
}
+1 propre et direct. C'est tout ce dont vous avez besoin pour faire sauter la pile. –
Pouvons-nous le raccourcir? Oui nous pouvons! 'void _() {_();} ... c'est presque comme Perl;) – Thomas
La différence est qu'en Perl, il est plus probable que vous allez souffler * votre * pile avant que Perl ne le fasse. – Rob
Cet exemple montre une récursivité incontrôlée. Finalement, la pile espacé alloué à ce processus sera complètement écrasé par des instances de bar et ret ...
int foo(int bar)
{
int ret = foo(42);
return ret;
}
continuer à essayer de revenir principale jusqu'à ce que la pile est épuisée?
int main(int argc, char **argv)
{
return main(argc, argv);
}
Il n'est pas légal d'appeler main() en C++. – Tmdean
Je sais qu'il ne formatera pas correctement, mais il n'y a pas d'avertissement avec '-Wall' même pour ce programme plus approprié: int main(int argc, char **argv) { if (argc == 0){return 0;} else {std::cout << argc << std::endl; return main(0, argv);} }
–
Je veux dire qu'il est étrange que' g ++ 'ne donne aucun avertissement quand vous appelez main; vous avez en effet raison (d'après ce que j'ai vu) que la norme ne permet pas d'appeler 'main'. –
récursion infinie:
void infiniteFunction() { infiniteFunction(); } int main() { infiniteFunction(); return 0; }
est ici qui pourrait se produire dans la pratique:
int factorial(int x) {
return x == 0 ? 1 : x * factorial(x-1);
}
Cette pile déborde la pour x
négative. Et, as Frank Krueger mentioned, également pour trop grand (mais alors int
déborderait d'abord).
Comme pour modifier :-)
void ping()
{
pong();
}
void pong()
{
ping();
}
Aussi, je crois que vous pouvez obtenir un débordement de pile si vous essayez d'allouer plus d'espace que la taille maximale de la pile de fil (1 Mo par défaut dans VS), donc quelque chose comme int a[100000];
devrait fournir l'exception.
appelez-les ping et pong lol Nice one –
ouais, un nom humoristique! –
Je ne peux pas croire que nous ayons omis le plus grand exemple de récurrence de tous les temps, factoriel!
#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));
}
Sur OS X 10.5.8 avec 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
Malheureusement, OS X fait état d'une "Segmentation fault" au lieu d'un "débordement de pile". Dommage.
Vous pouvez également obtenir un débordement de pile si vous essayez de placer des objets volumineux sur la pile (valeur de référence).
Si vous voulez générer un programme explicitement non récurrent pour entraîner un débordement de pile par les appels de fonction:
#!/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; }"
Exemple de sortie:
$ 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; }
Exemple d'utilisation:
$ python recursion.py 250000 | g++ -x c++ - && ./a.out
Au moins sur mon système, la pile d'appels s semble être 174602, donc vous aurez besoin de mettre l'argument à recursion.py
pour être plus grand que cela; et il faut quelques minutes pour compiler et lier le programme.
exemple Compile temps:
template <int N>
struct Factorial {
enum { value = N * Factorial<N - 1>::value };
};
// ...
{
int overflow = Factorial<10>::value;
}
Vous voulez que je mettre en œuvre le tout le site stackoverflow en C++ dans ma réponse? Wow ... :) – dicroce
@dicroce: lol +1 :-) –
Pourquoi la récursion infinie n'est-elle pas une réponse acceptable? – outis