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