Was ist in C und C ++ der Unterschied zwischen exit()
und abort()
? Ich versuche mein Programm nach einem Fehler zu beenden (keine Ausnahme).
Was ist in C und C ++ der Unterschied zwischen exit()
und abort()
? Ich versuche mein Programm nach einem Fehler zu beenden (keine Ausnahme).
Antworten:
abort()
Beendet Ihr Programm, ohne die zuerst registrierten Funktionen aufzurufen atexit()
und ohne zuerst die Destruktoren der Objekte aufzurufen. exit()
macht beides, bevor Sie Ihr Programm beenden. Destruktoren für automatische Objekte werden jedoch nicht aufgerufen. So
A a;
void test() {
static A b;
A c;
exit(0);
}
Wird zerstören a
und b
richtig, aber wird nicht Destruktoren von nennen c
. abort()
würde keine Destruktoren von beiden Objekten nennen. Da dies unglücklich ist, beschreibt der C ++ - Standard einen alternativen Mechanismus, der eine ordnungsgemäße Beendigung sicherstellt:
Objekte mit automatischer Speicherdauer werden alle in einem Programm zerstört, dessen Funktion
main()
keine automatischen Objekte enthält und den Aufruf von ausführtexit()
. Die Kontrolle kann direkt auf eine solche übertragen werden,main()
indem eine Ausnahme ausgelöst wird, die erfasst wirdmain()
.
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);
}
}
Statt Aufruf exit()
, ordnet diesen Code throw exit_exception(exit_code);
stattdessen.
abort sendet ein SIGABRT-Signal, exit schließt nur die Anwendung, die eine normale Bereinigung durchführt.
Sie können ein Abbruchsignal nach Belieben verarbeiten. Standardmäßig wird die Anwendung jedoch auch mit einem Fehlercode geschlossen.
Abort führt keine Objektzerstörung Ihrer statischen und globalen Mitglieder durch, Exit jedoch.
Wenn die Anwendung vollständig geschlossen ist, gibt das Betriebssystem natürlich nicht freigegebenen Speicher und andere Ressourcen frei.
Sowohl bei Abbruch und Ausfahrt Programmabbruch (vorausgesetzt , Sie das Standardverhalten nicht außer Kraft setzen), wird der Return - Code an den übergeordneten Prozess zurückgeführt werden , die Ihre Anwendung gestartet.
Siehe folgendes Beispiel:
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;
}
Bemerkungen:
Wenn der Abbruch nicht kommentiert ist, wird nichts gedruckt und der Destruktor eines Objekts wird nicht aufgerufen.
Wenn der Abbruch wie oben kommentiert wird: Ein Objektzerstörer wird aufgerufen, Sie erhalten die folgende Ausgabe:
Ausgangsfunktion 2
Ausgangsfunktion 1
Folgendes passiert, wenn ein Programm exit
() aufruft :
atexit
Funktionen werden ausgeführttmpfile
werden entferntDie abort
Funktion () sendet das SIGABRT
Signal an den aktuellen Prozess. Wenn es nicht abgefangen wird, wird das Programm ohne Garantie beendet, dass offene Streams gelöscht / geschlossen werden oder dass temporäre Dateien, die über erstellt tmpfile
wurden, entfernt werden, atexit
registrierte Funktionen nicht aufgerufen werden und eine Nicht-Funktion Der Exit-Status Null wird an den Host zurückgegeben.
Von der Handbuchseite exit ():
Die Funktion exit () bewirkt eine normale Prozessbeendigung und der Wert von Status & 0377 wird an das übergeordnete Element zurückgegeben.
Von der abort () Handbuchseite:
Mit abort () wird zuerst das SIGABRT-Signal entsperrt und dieses Signal dann für den aufrufenden Prozess ausgelöst. Dies führt zu einer abnormalen Beendigung des Prozesses, es sei denn, das SIGABRT-Signal wird abgefangen und der Signalhandler kehrt nicht zurück.
abort
sendet das SIGABRT
Signal. abort
kehrt nicht zum Anrufer zurück. Der Standardhandler für das SIGABRT
Signal schließt die Anwendung. stdio
Dateistreams werden geleert und dann geschlossen. Destruktoren für C ++ - Klasseninstanzen sind dies jedoch nicht (nicht sicher - vielleicht sind die Ergebnisse undefiniert?).
exit
hat seine eigenen Rückrufe, gesetzt mit atexit
. Wenn Rückrufe angegeben werden (oder nur einer), werden sie in umgekehrter Reihenfolge wie ihre Registrierungsreihenfolge aufgerufen (wie ein Stapel), und das Programm wird beendet. Wie bei abort
, exit
kehrt nicht zum Anrufer zurück. stdio
Dateistreams werden geleert und dann geschlossen. Außerdem werden Destruktoren für C ++ - Klasseninstanzen aufgerufen.