2013-04-20 9 views
5

Aby poznać limit wywołań rekurencyjnych w C++, wypróbowałem tę funkcję!Limit wywołań rekursywnych w C++ (około 5000)?

void recurse (int count) // Each call gets its own count 
{ 
printf("%d\n",count); 
    // It is not necessary to increment count since each function's 
    // variables are separate (so each count will be initialized one greater) 
    recurse (count + 1); 
} 

ten program zatrzyma się, gdy liczba jest równa 4716! więc limit wynosi zaledwie 4716 !! Jestem trochę zdezorientowany !! dlaczego program kończy się z egzekwowaniem, gdy liczba jest równa 4716 !! PS: Wykonywany w Visual Studio 2010. dzięki

Odpowiedz

11

Limit połączeń cyklicznych zależy od rozmiaru stosu. Język C++ nie ogranicza tego (z pamięci istnieje niższy limit liczby wywołań funkcji, które muszą być obsługiwane przez zgodny z normą kompilator, i jest to dość mała wartość).

I tak, powtarzanie "nieskończenie" zatrzyma się w którymś momencie. Nie jestem do końca pewien, czego jeszcze możesz się spodziewać.

Warto zauważyć, że projektowanie oprogramowania do wykonywania "bezkresowych" rekursji (lub rekursji, która działa w setkach lub tysiącach) jest bardzo złym pomysłem. Nie ma (standardowego) sposobu na określenie limitu stosu i nie można odzyskać po awarii przepełnienia stosu.

Po dodaniu tablicy lub innej struktury danych [i użycia jej, aby nie została ona zoptymalizowana], limit rekursji maleje, ponieważ każda klatka stosu zużywa więcej miejsca na stos.

Edycja: faktycznie oczekiwałbym wyższego limitu, podejrzewam, że kompilujesz swój kod w trybie debugowania. Jeśli skompilujesz go w trybie zwolnienia, spodziewam się, że otrzymasz kilka tysięcy więcej, być może nawet nieskończonych, ponieważ kompilator konwertuje rekursję ogona w pętlę.

+0

Bezgraniczna rekursja jest możliwa na niektórych celach. GCC obsługuje coś, co nazywa się "split stacks", co pozwala rosnąć stosom, * dyskretnie, * wypełniać dostępną pamięć. Zobacz http://gcw.gnu.org/wiki/SplitStacks –

+0

Wiem, że był limit, ale zastanawiam się, co to za limit! Nie spodziewałem się, że stos eksploduje za mniej niż 5000 połączeń! Dziękuję za wyjaśnienie ! – satyres

+0

Ciągle jest limit i nadal jest (o ile rozumiem) brak możliwości wykrycia końca stosu. Używając stosu oprogramowania, istnieje przynajmniej sposób na wykrycie, kiedy skończy się stos ... –

1

Prawdopodobnie zabrakło miejsca na stosie.

Za każdym razem, gdy wywoływana jest funkcja rekursywna, musi ona przesłać adres zwrotny na stosie, aby wiedział, gdzie powrócić po wywołaniu funkcji.

To zawiesza się w 4716, ponieważ po prostu kończy się przestrzeń na stosie po około 4716 iteracjach.

+0

ale jest za mały !! tylko 5000 połączeń! jak poznać maksymalny rozmiar stosu! – satyres

+0

Myślałem, że rozmiar stosu był związany z rozmiarem pamięci komputera! więc muszę to zmienić w VS2010! – satyres

+1

Domyślny rozmiar stosu jest zwykle ustawiony w pliku wykonywalnym. Nie wiem, skąd wziął się pomysł, że jest to związane z ilością pamięci komputera. – tangrs

2

Rozmiar stosu zależy od środowiska.

Na przykład w * NIX można zmodyfikować rozmiar stosu w środowisku, a następnie uruchomić program, a wynik będzie inny.

W Windows, możesz zmienić to w ten sposób (source):

$ editbin /STACK:reserve[,commit] program.exe 
+0

dziękuję bardzo za te informacje! – satyres

Powiązane problemy