exit() stets unproblematisch?



  • Ist die Funktion 'exit()' aus <cstlib> jedenfalls eine unproblematische Möglichkeit, eine Anwendung zu beenden. Laut msdn ruft exit() angeblich nicht die Destruktoren von 'automatischen Objekten' auf. Bezüglich dynamischen Speichers sollte das ja trotzdem kein Problem sein (wegen Speicherlecks), weil ja kurz nachdem meine Anwendung die Kontrolle an die CRT zurückgibt, de-allokiert doch die CRT auch sämtlichen Dynamischen Speicher, den sie für meine Anwendung beim OS beantragt hat (kurz bevor auch die CRT selbst 'entladen' wird)?
    Wie sieht die Sache allerdings mit Hardware- (z.B. Vertex-) Buffern aus? Werden die ihrerseits z.B. von der d3d9.dll auch wieder aufgeräumt, wenn meine Anwendung (weil plötzlich ein sofortiger Programm-Abbruch notwendig geworden ist) exit() aufruft?
    In wie weit fallen Aufräumarbeiten eigentlich in die Zuständigkeit meines Programms, und welche Dinge erledigen die CRT oder andere dazugeladene DLLs selbständig?
    Und bietet eventuell abort() Vorteile gegenüber exit()?



  • Wird alles von deinem Betriebssystem aufgeräumt, ist aber extrem schlechter Stil.


  • Mod

    Ich glaube du verwechselst da etwas: exit sollte eigentlich alles sauber abräumen, es ist abort welches einfach direkt abbricht.
    edit: Kleiner Irrtum: exit ruft doch keine Destruktoren auf, aber immerhin führt es eventuelle exit-Funktionen aus.

    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    class has_destructor
    {
    public:
      ~has_destructor(){cout<<"Destruktor aufgerufen"<<endl;}
    };
    
    void exit_function ()
    {
      cout<<"Exit function aufgerufen"<<endl;
    }
    
    int main ()
    {
      atexit (exit_function);
      has_destructor automatisches_objekt;
    
      cout<<"1 für normales Ende, 2 für exit, 3 für abort"<<endl;
      int choice;
      cin >> choice;
      switch(choice)
        {
        case 1: return 0;
        case 2: exit(0);
        case 3: abort();
        }
    }
    


  • Wenn du im Programmfluss auf ein Problem stößt, sollte eine (wenn dann) nötige Terminierung über eine Exception laufen. Die wird bis ganz unten durchgereicht, auf dem Weg dahin werden automatische Objekte zerstört. Dabei ist ja nicht nur die Speicherfreigabe entscheidend sondern der Destruktorcode! Dort werden (hoffentlich!) alle Aufräumarbeiten durchgeführt, die notwendig sind. Und sicherlich auch noch andere Sachen - z.B. Settings schreiben, Files geschlossen, Locks entfernt, Datenbankeverbindungen gekappt, usw.



  • l'abra d'or schrieb:

    ...Die wird bis ganz unten durchgereicht, auf dem Weg dahin werden automatische Objekte zerstört. ...

    Aber nur, wenn sie gefangen wird.... Ohne passendes catch wird auch kein "stack unwinding" gemacht.
    Ich glaube, das ist zwar der Runtime überlassen, es trotzdem zu tun, aber soweit ich weiß, tut's keine (aus gutem Grund).

    Gruß,

    Simon2.



  • Ohne passendes catch gibts einen core dump (auf Linux, unter anderen OS eben deren Äquivalent) geschrieben, es wird also ein Absturz simuliert. Das ist was anderes als eine exit();



  • In wie weit fallen Aufräumarbeiten eigentlich in die Zuständigkeit meines Programms

    Du raeumst doch auch selbst dein Zimmer auf. Also raeume auch deinen Muell beim programmieren selbst weg. Gehoert zum Erwachsen werden dazu.



  • Tyrdal schrieb:

    Ohne passendes catch ...

    Schön, dass Du nochmal meine Aussage untermauerst (kein exit(), das ein stack-unwinding macht).
    Mal etwas "standardiger":

    Tyrdal schrieb:

    ... gibts einen core dump ...

    Nunja, das ist - soweit ich weiß - kein "C++-Begriff".
    Der Standard sagt:
    - Im Fall einer nicht gefangen Exception wird terminate() aufgerufen (Kap 15.5.1, 2. Spiegelstrich),
    - das (falls kein eigener terminate-handler installiert ist) abort() aufruft (Kap. 18.6.3), das
    - kein stack unwinding macht (Kap 18.3.3, "...without executing destructors for objects of automatic or static storage duration and without calling the functions passed to atexit() ..." ).

    Mehr habe ich nicht behauptet.

    Die Stoßrichtung meiner Aussage war aber eine andere: l'abra d'or schrieb ohne weitere Einschränkung, dass beim "Durchreichen von Exception" automatische Objekte zerstört würden. Ich habe lediglich auf die Einschränkung hingewiesen, dass das nur in dem Fall gilt, dass die Exception noch gefangen wird.

    Ergo: Das Werfen einer Exception ist nicht per se mit Aufräumen verbunden (im Gegensatz zum Aufruf von exit())....

    Gruß,

    Simon2.


Anmelden zum Antworten