1 #include <fstream>
   2 #include <iostream>
   3 #include <sstream>
   4 #include <memory>
   5 using namespace std;
   6 
   7 #include "tableau7.hpp"
   8 
   9 typedef tableau<int> Tint;
  10 
  11 // tableauO contient deux OBJETS de type tableau
  12 // Pas de fuite de mémoire, bien que la construction du second tableau génère une exception
  13 class tableauO {
  14     private:
  15         Tint T1;
  16         Tint T2;
  17     
  18     public:
  19         tableauO(int s1, int s2): T1(s1),T2(s2) {
  20             cerr << "constructeur de tableauO\n";
  21         };
  22         ~tableauO() {
  23             cerr << "destructeur de tableauO\n";
  24         };
  25 };
  26 
  27 // tableauF contient deux pointeurs vers des tableaux - Pb si la construction du second objet déclenche une instruction
  28 // Pour observer, n'oubliez pas de faire AVANT L'EXECUTION: ulimit -v 200000
  29 // Ouvrez un top dans une autre fenêtre
  30 // Lancez le programme et observez la mémoire virtuelle: elle monte jusqu'à 200Mo, puis ça plafonne
  31 
  32 class tableauF {
  33     private:
  34         Tint* T1;
  35         Tint* T2;
  36     
  37     public:
  38         tableauF(int s1,int s2) {
  39             cerr << "constructeur de tableauF\n";
  40                 T1 = new Tint(s1);
  41                 T2 = new Tint(s2);
  42         };
  43         ~tableauF() {
  44             cerr << "destructeur de tableauF\n";
  45                 delete (T1);
  46                 T1=NULL;
  47                 delete (T2);
  48                 T2=NULL;
  49         };
  50 };
  51 
  52 // dans tableauA, on a remplacé les pointeurs par des auto_ptr. On n'a plus de fuite de mémoire !!! 
  53 
  54 class tableauA {
  55     private:
  56         auto_ptr<tableau<int> > T1;     // ATTENTION auto_ptr<tableau<int>> T1; ne marchera pas, le compilo va se prendre les pieds dans le tapis
  57         auto_ptr<tableau<int> > T2;
  58     
  59     public:
  60         tableauA(int s1, int s2):T1(new Tint(s1)),T2(new Tint(s2)) {
  61             cerr << "constructeur de tableauA\n";
  62         };
  63         // Pas besoin de détruire T1/T2, c'est l'auto_ptr qui s'en charge
  64         ~tableauA() {
  65             cerr << "destructeur de tableauA\n";
  66         };
  67 };
  68 
  69 // Choisissez ci-dessous le type de tableau que vous souhaitez essayer
  70 typedef tableauO tableauZ;
  71 //typedef tableauF tableauZ;
  72 //typedef tableauA tableauZ;
  73 
  74 // choisissez ci-dessous le type d'essai que vous voulez réaliser
  75 //#define FUITE
  76 //#define RESPONSABILITE
  77 #define CONST
  78 
  79 main() {
  80 
  81 /* Fuite de mémoire:
  82        N'oubliez pas de taper: ulimit -v 200000
  83        Observez la fuite à l'aide de top dans une autre fenêtre
  84        ça fuit dans le cas de tableauF, tableauO et tableauA se comportent correctement
  85 */
  86 #ifdef FUITE
  87     for (;;) {
  88         try {
  89             tableauZ f(1000,1000000000);
  90         } catch(const exception &e) {
  91             cerr << e.what() << '\n';
  92         };
  93     };
  94 #endif
  95 
  96 /* Responsabilité:
  97        Supprimez la macro FUITE, sinon ce code ne sera jamais exécuté
  98        L'opérateur= ne marche pas dans le cas de tableauO (pas la même dimension)
  99        L'opérateur= marche dans le cas de tableauF, mais ensuite ça plante (ben oui !)
 100        Le programme MARCHE BIEN dans le cas de tableauA, car l'opérateur= corresopnd à un passage de responsabilité des pointeurs
 101 */
 102 
 103 #ifdef RESPONSABILITE
 104     cerr << "naissance de B1 10 10\n";
 105     tableauZ B1(10,10);
 106     {
 107         cerr << "naissance de A1 1000 1000\n";
 108         tableauZ A1(1000,1000);
 109         
 110         cerr << "B1=A1\n";
 111         B1=A1;
 112         
 113         cerr << "Fin de A1\n";
 114     }
 115     cerr << "Fin de B1 et du programme\n";
 116 #endif
 117 
 118 /* dans une égalité, le membre de droite ne peut être constant
 119        Le code suivant refuse de compiler dans le cas tableauA
 120 */
 121 
 122 #ifdef CONST
 123     const tableauZ A1(10,10);
 124     tableauZ B1(10,10);
 125     B1 = A1;
 126 #endif
 127 
 128 };
 129