it-swarm.com.de

Was ist der Unterschied zwischen exit () und abort ()?

Was ist der Unterschied zwischen exit() und abort() in C und C++? Ich versuche mein Programm nach einem Fehler zu beenden (keine Ausnahme).

126
Nathan Stoddard

abort() beendet Ihr Programm, ohne zuvor die mit atexit() registrierten Funktionen und die Destruktoren der Objekte aufzurufen. exit() erledigt beides, bevor Sie Ihr Programm beenden. Es werden jedoch keine Destruktoren für automatische Objekte aufgerufen. So

A a;
void test() { 
    static A b;
    A c;
    exit(0);
}

Zerstört a und b ordnungsgemäß, ruft jedoch keine Destruktoren von c auf. abort() würde keine Destruktoren von beiden Objekten aufrufen. Da dies bedauerlich 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 exit() ausführt. Die Steuerung kann direkt auf eine solche main() übertragen werden, indem eine Ausnahme ausgelöst wird, die in main() enthalten ist.

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);
    }
}

Anstatt exit() aufzurufen, ordnen Sie stattdessen den Code throw exit_exception(exit_code); an.

113

Abbruch sendet ein SIGABRT-Signal, Beenden schließt nur die Anwendung, die eine normale Bereinigung durchführt.

Sie können ein Abbruch Signal behandeln, wie Sie möchten, aber das Standardverhalten besteht darin, die Anwendung ebenfalls mit einem Fehlercode zu schließen.

Abbruch führt keine Objektzerstörung Ihrer statischen und globalen Member durch, Beenden jedoch.

Wenn die Anwendung jedoch vollständig geschlossen ist, gibt das Betriebssystem nicht freigegebenen Speicher und andere Ressourcen frei.

In beiden Fällen, Abbruch und Beenden (vorausgesetzt, Sie haben das Standardverhalten nicht außer Kraft gesetzt), wird der Rückkehrcode an den übergeordneten Prozess zurückgegeben, der Ihre Anwendung gestartet hat.

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 abort nicht kommentiert ist, wird nichts gedruckt und der Destruktor eines Objekts wird nicht aufgerufen.

  • Wenn abort wie oben kommentiert wird: irgendein Objektdestruktor wird aufgerufen, erhalten Sie die folgende Ausgabe:

austrittsfunktion 2
Funktion verlassen 1

32
Brian R. Bondy

Die folgenden Dinge passieren, wenn ein Programm exit () aufruft:

  • Von der Funktion atexit registrierte Funktionen werden ausgeführt
  • Alle offenen Streams werden gelöscht und geschlossen, von tmpfile erstellte Dateien werden entfernt
  • Das Programm wird mit dem angegebenen Beendigungscode für den Host beendet

Die Funktion abort () sendet das Signal SIGABRT an den aktuellen Prozess. Wenn es nicht abgefangen wird, wird das Programm ohne Garantie beendet, dass offene Streams gelöscht/geschlossen oder temporäre Dateien erstellt werden über tmpfile werden entfernt, atexit registrierte Funktionen werden nicht aufgerufen und ein Nicht-Null-Beendigungsstatus wird an den Host zurückgegeben.

10
Robert Gamble

Von der Manpage exit () aus:

Die exit () - Funktion führt zu einer normalen Prozessbeendigung und der Wert von Status & 0377 wird an das übergeordnete Element zurückgegeben.

Aus der Manpage abort ():

Das abort () entsperrt zuerst das SIGABRT-Signal und löst dann dieses Signal für den aufrufenden Prozess aus. Dies führt zu einer abnormalen Beendigung des Prozesses, es sei denn, das SIGABRT-Signal wird abgefangen und der Signalhandler kehrt nicht zurück.

5

abort sendet das SIGABRT Signal. abort kehrt nicht zum Anrufer zurück. Der Standardhandler für das Signal SIGABRT schließt die Anwendung. stdio Dateistreams werden geleert und dann geschlossen. Destruktoren für C++ - Klasseninstanzen gibt es jedoch nicht (in diesem Fall nicht sicher - sind die Ergebnisse möglicherweise nicht definiert?).

exit hat seine eigenen Rückrufe, die mit atexit festgelegt werden. Wenn Rückrufe angegeben sind (oder nur einer), werden sie in umgekehrter Reihenfolge ihrer Registrierungsreihenfolge (wie ein Stapel) aufgerufen, und das Programm wird beendet. Wie bei abort kehrt exit nicht zum Aufrufer zurück. stdio Dateistreams werden geleert und dann geschlossen. Außerdem werden Destruktoren für C++ - Klasseninstanzen aufgerufen.

4
strager