2014-06-06 14 views
5
#include <stdio.h> 
int main(void) 
{ 
    int (*fp)(void); 
    printf("Loopy.\n"); 
    fp = &main; //point to main function 
    fp(); //call 'main' 

    return 0; 
} 

Zamiast nieskończenie wykonywać pętlę, "pętla" wykonuje się na około 10-20 sekund na moim komputerze, a następnie otrzymuje standardowy raport awarii aplikacji systemu Windows. Dlaczego to?Wskaźniki funkcji - Dlaczego ten kod ulega awarii?

Kompilator: GCC IDE: Code :: Blocks OS: Win7 64bit

enter image description here

+0

[Working w porządku dla mnie] (http://ideone.com/Qzcc3Q). Nie można odtworzyć. – haccks

+4

Kod wyjątku '0xc00000fd' to przepełnienie stosu. Czego się spodziewałeś? –

+0

@AustinBrunkhorst Spodziewałem się nieskończonej pętli, eksperymentowałem. Podobnie jak zdecydowana większość ludzi nie czytałem szczegółów katastrofy :). –

Odpowiedz

8

10..20 sekund jest tak długo, jak długo trwa komputer do przepełnienia stosu.

Nowa ramka stosu jest tworzona za każdym razem, gdy funkcja wywołuje się rekursywnie za pomocą wskaźnika funkcji. Ponieważ wywołanie jest wykonywane pośrednio, kompilator nie ma szansy na zoptymalizowanie wywołania ogona w pętli, więc program w końcu ulega awarii z przepełnieniem stosu.

Jeśli utrwalisz pętlę po określonej liczbie razy, powiedzmy, ustawiając licznik, Twój program będzie działał poprawnie do zakończenia (demo).

#include <stdio.h> 

int counter = 200; 

int main(void) 
{ 
    int (*fp)(void); 
    printf("Loopy %d\n", counter); 
    fp = &main; //point to main function 
    if (counter--) { 
     fp(); //call 'main' 
    } 
    return 0; 
} 
+0

Fantastyczna odpowiedź, ostatnio uczono o stosach ramek, powinienem był to zobaczyć! Dziękuję Ci. –

1

zachowanie jest kompilator zależne może upaść po przepełnienia stosu lub po prostu powiesić tam bez żadnych odpowiedzi, ale jedynym powodem może być pchania zbyt wiele ramek stosu w stosie pamięci