===== Stack Unwinding ===== Κατά την δημιουργία ενός //exception// μέσα σε μία συνάρτηση ή σε ένα κατασκευαστή δεν είναι απαραίτητο ότι η διαχείριση του //exception// θα πρέπει να γίνει στην ίδια τη συνάρτηση ή τον καστασκευαστή. Η διαδικασία όνομάζεται //stack unwinding// και το παράδειγμα που ακολουθεί είναι εξαρειτικά διαφωτιστικό για το πως διαμορφώνεται το stack μετά από την διαχείριση μίας εξαίρεσης σε υψηλότερο επίπεδο. #include #include using namespace std; class Vector { int *array; int size; public: Vector(int length=0); ~Vector(); }; #include "Vector.hpp" Vector::Vector(int length) { cout << "Create vector of size: " << length << endl; size = length; array = new (nothrow) int[size]; if(array==NULL) { cerr << "Memory allocation failure!" << endl; exit(-1); } for(int i=0; i #include #include #include "Vector.hpp" using namespace std; // called by FFF() void FFFF() { std::cout << "Start FFFF\n"; Vector v(4); std::cout << "FFFF throwing int literal exception\n"; throw 100; std::cout << "End FFFF\n"; } // called by FF() void FFF() { std::cout << "Start FFF\n"; Vector v(3); FFFF(); std::cout << "End FFF\n"; } // called by F() void FF() { std::cout << "Start FF\n"; Vector v(2); try { FFF(); } catch(char) { std::cerr << "FF caught char exception\n"; } std::cout << "End FF\n"; } // called by main() void F() { std::cout << "Start F\n"; Vector v(1); try { FF(); } catch (int) { std::cerr << "F caught int exception\n"; } catch (char) { std::cerr << "F caught char exception\n"; } std::cout << "End F\n"; } int main() { std::cout << "Start main\n"; try { F(); } catch (int) { std::cerr << "main caught int exception\n"; } std::cout << "End main\n"; return 0; } Το αποτέλεσμα που εκτυπώνεται στην οθόνη είναι το εξής: Start main Start F Create vector of size: 1 Start FF Create vector of size: 2 Start FFF Create vector of size: 3 Start FFFF Create vector of size: 4 FFFF throwing int literal exception ~Destroying vector of size: 4 ~Destroying vector of size: 3 ~Destroying vector of size: 2 F caught int exception End F ~Destroying vector of size: 1 Η εξέλιξη του //program stack// στο παρακάτω πρόγραμμα δίνεται στο παρακάτω διάγραμμα. Παρατηρήστε ότι το exception παράγεται στη συνάρτηση **FFFF()**, αλλά η διαχείριση του γίνεται στην **F()** πράγμα που συνεπάγεται την αυτόματη συρρίκνωση του //stack// στο επίπεδο της συνάρτησης **F()**. Μετά τη διαχείριση του //exception//, τα περιεχόμενα του //stack// για τις συναρτήσεις **FFFF()**, **FFF()**και **FF()** έχουν χαθεί. Από τις εκτυπώσεις στην οθόνη, παρατηρήστε επίσης ότι όσα αντικείμενα έχουν δημιουργηθεί αυτόματα μέσα στο stack στις συναρτήσεις FF(), FFF(), FFFF() καταστρέφονται (με κλήση του αντίστοιχου καταστροφέα) και απελευθερώνεται η μνήμη που έχει δεσμευθεί για αυτά. Η διαδικασία καταστροφής των αντικειμένων γίνεται αυτόματα κατά τη διαδικασία του stack unwinding, ώστε να μην υπάρχουν απώλειες πόρων (memory leaks, περιγραφείς αρχείων ή sockets που παραμένουν ανοιχτά) μετά την διακοπή της εξαίρεσης. {{ :cpp:stack_unwinding.png |}}