Jaka jest różnica między exit()
i w językach C i C ++ abort()
? Próbuję zakończyć program po błędzie (nie jest to wyjątek).
abort()
zamyka program bez wywoływania funkcji zarejestrowanych jako atexit()
pierwsze i bez uprzedniego wywoływania destruktorów obiektów. exit()
robi obie te rzeczy przed wyjściem z programu. Nie wywołuje jednak destruktorów dla obiektów automatycznych. Więc
A a;
void test() {
static A b;
A c;
exit(0);
}
Zniszczy a
i b
poprawnie, ale nie wywoła destruktorów c
. abort()
nie nazwałby destruktorów żadnego z obiektów. Ponieważ jest to niefortunne, w standardzie C ++ opisano alternatywny mechanizm zapewniający prawidłowe zakończenie:
Obiekty z automatycznym czasem trwania są niszczone w programie, którego funkcja
main()
nie zawiera automatycznych obiektów i wykonuje wywołanieexit()
. Kontrolę można przekazać bezpośrednio do takiegomain()
, rzucając wyjątek, który jest przechwytywanymain()
.
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
int main() {
try {
// put all code in here
} catch(exit_exception& e) {
exit(e.c);
}
}
Zamiast dzwonić exit()
, zaaranżuj ten kod throw exit_exception(exit_code);
.
abort wysyła sygnał SIGABRT, exit zamyka tylko aplikację wykonującą normalne czyszczenie.
Możesz obsłużyć sygnał przerwania , jak chcesz, ale domyślnym zachowaniem jest zamknięcie aplikacji również z kodem błędu.
abort nie spowoduje zniszczenia obiektów statycznych i globalnych członków, ale zakończy działanie .
Oczywiście, gdy aplikacja zostanie całkowicie zamknięta, system operacyjny zwolni niewykorzystaną pamięć i inne zasoby.
Zarówno w przypadku przerwania, jak i zakończenia programu wyjściowego (zakładając, że nie nadpisałeś domyślnego zachowania), kod powrotu zostanie zwrócony do procesu nadrzędnego, który uruchomił Twoją aplikację.
Zobacz poniższy przykład:
SomeClassType someobject; void myProgramIsTerminating1(void) { cout<<"exit function 1"<<endl; } void myProgramIsTerminating2(void) { cout<<"exit function 2"<<endl; } int main(int argc, char**argv) { atexit (myProgramIsTerminating1); atexit (myProgramIsTerminating2); //abort(); return 0; }
Uwagi:
Jeśli abort nie jest komentowany: nic nie jest drukowane, a destruktor jakiegoś obiektu nie zostanie wywołany.
Jeśli abort jest komentowane jak powyżej: zostanie wywołany jakiś destruktor obiektów, otrzymasz następujący wynik:
źródło
Następujące rzeczy mają miejsce, gdy program wywołuje
exit
():atexit
funkcjętmpfile
są usuwaneFunkcja
abort
() wysyłaSIGABRT
sygnał do bieżącego procesu, jeśli nie zostanie przechwycony, program zostanie zakończony bez gwarancji, że otwarte strumienie zostaną opróżnione / zamknięte lub że pliki tymczasowe utworzone za pomocątmpfile
zostaną usunięte,atexit
zarejestrowane funkcje nie zostaną wywołane, a zerowy kod wyjścia jest zwracany do hosta.źródło
Ze strony podręcznika exit ():
Ze strony podręcznika abort ():
źródło
abort
wysyłaSIGABRT
sygnał.abort
nie wraca do dzwoniącego. Domyślna obsługaSIGABRT
sygnału zamyka aplikację.stdio
strumienie plików są opróżniane, a następnie zamykane. Destruktory dla instancji klas C ++ nie są jednak (nie jesteś pewien tego - być może wyniki są nieokreślone?).exit
ma własne wywołania zwrotne, ustawiane za pomocąatexit
. Jeśli podano wywołania zwrotne (lub tylko jeden), są one wywoływane w kolejności odwrotnej do ich kolejności rejestracji (jak stos), a następnie program kończy działanie. Podobnie jak w przypadkuabort
,exit
nie wraca do dzwoniącego.stdio
strumienie plików są opróżniane, a następnie zamykane. Wywoływane są również destruktory dla instancji klas C ++.źródło