User Tools

Site Tools


cpp:stack_unwinding

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
cpp:stack_unwinding [2019/05/06 08:12] gthanoscpp:stack_unwinding [2023/05/15 14:13] (current) gthanos
Line 2: Line 2:
  
 Κατά την δημιουργία ενός //exception// μέσα σε μία συνάρτηση ή σε ένα κατασκευαστή δεν είναι απαραίτητο ότι η διαχείριση του //exception// θα πρέπει να γίνει στην ίδια τη συνάρτηση ή τον καστασκευαστή. Η διαδικασία όνομάζεται //stack unwinding// και το παράδειγμα που ακολουθεί είναι εξαρειτικά διαφωτιστικό για το πως διαμορφώνεται το stack μετά από την διαχείριση μίας εξαίρεσης σε υψηλότερο επίπεδο. Κατά την δημιουργία ενός //exception// μέσα σε μία συνάρτηση ή σε ένα κατασκευαστή δεν είναι απαραίτητο ότι η διαχείριση του //exception// θα πρέπει να γίνει στην ίδια τη συνάρτηση ή τον καστασκευαστή. Η διαδικασία όνομάζεται //stack unwinding// και το παράδειγμα που ακολουθεί είναι εξαρειτικά διαφωτιστικό για το πως διαμορφώνεται το stack μετά από την διαχείριση μίας εξαίρεσης σε υψηλότερο επίπεδο.
 +
 +<code cpp Vector.hpp>
 +#include <iostream>
 +#include <cstdlib>
 +using namespace std;
 +
 +class Vector {
 +  int *array;
 +  int size;
 +  
 +public:
 +  Vector(int length=0);
 +  ~Vector();
 +};
 +</code>
 +
 +<code cpp Vector.cpp>
 +#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<size; i++)
 +    array[i] = 0;
 +}
 +
 +Vector::~Vector() {
 +  cout << "~Destroying vector of size: " << size << endl;
 +  delete [] array;
 +}
 +</code>
  
 <code cpp StackUnwinding.cpp> <code cpp StackUnwinding.cpp>
 #include <iostream> #include <iostream>
 +#include <cstdlib>
 +#include "Vector.hpp"
 +
 +using namespace std;
 +
 // called by FFF() // called by FFF()
 void FFFF() { void FFFF() {
   std::cout << "Start FFFF\n";   std::cout << "Start FFFF\n";
 +  Vector v(4);
   std::cout << "FFFF throwing int literal exception\n";   std::cout << "FFFF throwing int literal exception\n";
   throw 100;   throw 100;
Line 16: Line 58:
 void FFF() { void FFF() {
   std::cout << "Start FFF\n";   std::cout << "Start FFF\n";
 +  Vector v(3);
   FFFF();   FFFF();
   std::cout << "End FFF\n";   std::cout << "End FFF\n";
Line 22: Line 65:
 void FF() { void FF() {
   std::cout << "Start FF\n";   std::cout << "Start FF\n";
 +  Vector v(2);
   try {   try {
     FFF();     FFF();
   } catch(char) {    } catch(char) { 
-    std::cerr << "FF caught double exception\n";+    std::cerr << "FF caught char exception\n";
   }   }
   std::cout << "End FF\n";   std::cout << "End FF\n";
Line 32: Line 76:
 void F() { void F() {
   std::cout << "Start F\n";   std::cout << "Start F\n";
 +  Vector v(1);
   try {   try {
     FF();     FF();
Line 37: Line 82:
      std::cerr << "F caught int exception\n";      std::cerr << "F caught int exception\n";
   } catch (char) {   } catch (char) {
-     std::cerr << "F caught double exception\n";+     std::cerr << "F caught char exception\n";
   }   }
   std::cout << "End F\n";   std::cout << "End F\n";
Line 58: Line 103:
 Start main Start main
 Start F Start F
 +Create vector of size: 1
 Start FF Start FF
 +Create vector of size: 2
 Start FFF Start FFF
 +Create vector of size: 3
 Start FFFF Start FFFF
 +Create vector of size: 4
 FFFF throwing int literal exception FFFF throwing int literal exception
 +~Destroying vector of size: 4
 +~Destroying vector of size: 3
 +~Destroying vector of size: 2
 F caught int exception F caught int exception
 End F End F
-End main+~Destroying vector of size: 1
 </code> </code>
  
-εξέλιξη του //program stack// στο παρακάτω πρόγραμμα δίνεται στο παρακάτω διάγραμμα. Παρατηρήστε ότι το exception παράγεται στη συνάρτηση **FFFF()**, αλλά ιάνεταιστην **F()** πράγμα που συνεπάγεται την αυτόματη συρρίκνωση του //stack// στο επίπεδο της συνάρτησης **F()**. Μετά το "πιάσιμο" του //exception//, τα περιεχόμενα του //stack// για τις συναρτήσεις **FFFF()**, **FFF()**και **FF()** έχουν χαθεί.+Η εξέλιξη του //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 |}} {{ :cpp:stack_unwinding.png |}}
  
cpp/stack_unwinding.1557130341.txt.gz · Last modified: 2019/05/06 07:12 (external edit)