//PARTIE 1 : Allocation dynamique simple // Exercice 1 : Tableau dynamique #include using namespace std; int main() { int n; cout << "Donner la taille du tableau : "; cin >> n; if (n <= 0) { cout << "Taille invalide !" << endl; return 1; } // Allocation dynamique int* tableau = new int[n]; // Remplissage for (int i = 0; i < n; i++) { cout << "Element [" << i << "] : "; cin >> tableau[i]; } // Affichage cout << "\nContenu du tableau : "; for (int i = 0; i < n; i++) { cout << tableau[i] << " "; } // Somme int somme = 0; for (int i = 0; i < n; i++) { somme += tableau[i]; } cout << "\nSomme = " << somme << endl; // Libération mémoire delete[] tableau; return 0; } //PARTIE 2 : Classe TableauDynamique //Exercice 2 #include using namespace std; class TableauDynamique { private: int* data; int taille; public: // Constructeur TableauDynamique(int t) { taille = t; data = new int[taille]; } // Destructeur ~TableauDynamique() { delete[] data; cout << "Memoire liberee !" << endl; } void remplir() { for (int i = 0; i < taille; i++) { cout << "Element [" << i << "] : "; cin >> data[i]; } } void afficher() { for (int i = 0; i < taille; i++) { cout << data[i] << " "; } cout << endl; } void setValeur(int index, int valeur) { if (index >= 0 && index < taille) data[index] = valeur; } int getValeur(int index) { if (index >= 0 && index < taille) return data[index]; return -1; } }; //PARTIE 3 : Règle des trois // Exercice 3 //Ajout du constructeur de copie et de l’opérateur d’affectation. class TableauDynamique { private: int* data; int taille; public: // Constructeur TableauDynamique(int t) { taille = t; data = new int[taille]; } // Constructeur de copie (Deep Copy) TableauDynamique(const TableauDynamique& other) { taille = other.taille; data = new int[taille]; for (int i = 0; i < taille; i++) data[i] = other.data[i]; } // Opérateur d'affectation TableauDynamique& operator=(const TableauDynamique& other) { if (this != &other) { delete[] data; // éviter fuite mémoire taille = other.taille; data = new int[taille]; for (int i = 0; i < taille; i++) data[i] = other.data[i]; } return *this; } // Destructeur ~TableauDynamique() { delete[] data; } }; //PARTIE 4 : Classe Etudiant #include #include using namespace std; class Etudiant { private: char* nom; int age; public: // Constructeur Etudiant(const char* n, int a) { age = a; nom = new char[strlen(n) + 1]; strcpy(nom, n); } // Constructeur de copie Etudiant(const Etudiant& other) { age = other.age; nom = new char[strlen(other.nom) + 1]; strcpy(nom, other.nom); } // Opérateur d'affectation Etudiant& operator=(const Etudiant& other) { if (this != &other) { delete[] nom; age = other.age; nom = new char[strlen(other.nom) + 1]; strcpy(nom, other.nom); } return *this; } // Destructeur ~Etudiant() { delete[] nom; } void afficher() { cout << "Nom: " << nom << ", Age: " << age << endl; } }; /* Réponses aux Questions Théoriques 1?? Stack vs Heap Stack Heap Allocation automatique Allocation manuelle Rapide Plus flexible Taille limitée Grande capacité Détruite automatiquement Doit être libérée avec delete 2?? Si on oublie delete ? ? Fuite mémoire ? Mémoire reste occupée jusqu’à la fin du programme ? Problème critique dans applications longues 3?? delete vs delete[] delete ? pour un seul objet delete[] ? pour un tableau 4?? Règle des trois Si une classe gère une ressource dynamique, elle doit définir : Destructeur Constructeur de copie Opérateur d’affectation 5?? Fuite mémoire Mémoire allouée mais jamais libérée. */ //BONUS : Smart Pointers // Exemple avec unique_ptr #include using namespace std; unique_ptr ptr = make_unique(10); //Un seul propriétaire //Libération automatique //Exemple avec shared_ptr shared_ptr p1 = make_shared(20); shared_ptr p2 = p1; /* Compteur de références Libération automatique quand compteur = 0 // Comparaison unique_ptr shared_ptr Propriété unique Propriété partagée Plus léger Plus coûteux Sécurisé Flexible */