La libreria <memory> contiene gli strumenti principali per una gestione moderna e sicura della memoria in C++. In particolare fornisce i puntatori intelligenti (smart pointer), che permettono di evitare errori comuni come:
- memory leak
- delete dimenticati
- doppie deallocazioni
- puntatori pendenti
Gli smart pointer gestiscono automaticamente il ciclo di vita della memoria dinamica.
1️⃣ Inclusione della libreria
#include <memory>
using namespace std;
2️⃣ Tipi principali di Smart Pointer
| Smart Pointer | Caratteristiche | Descrizione |
|---|---|---|
| unique_ptr | Possesso esclusivo | Un solo proprietario del dato |
| shared_ptr | Possesso condiviso | Contatore delle referenze |
| weak_ptr | Riferimento debole | Non aumenta il contatore → evita cicli |
3️⃣ unique_ptr – Puntatore a possesso unico
È il più leggero e sicuro: solo un oggetto può possedere la risorsa.
unique_ptr p = make_unique(10);
cout << *p; // 10
✔ Non serve chiamare delete: la memoria viene liberata automaticamente.
Trasferire il possesso
unique_ptr a = make_unique(5);
unique_ptr b = move(a); // trasferimento
// a ora è nullptr
4️⃣ shared_ptr – Condivisione del possesso
Più variabili possono condividere lo stesso oggetto.
shared_ptr p1 = make_shared(30);
shared_ptr p2 = p1;
cout << p1.use_count(); // 2
La memoria viene liberata solo quando il contatore arriva a 0.
5️⃣ weak_ptr – Evita cicli tra shared_ptr
Un weak_ptr non possiede l oggetto, ma può osservarlo.
shared_ptr p = make_shared(50);
weak_ptr w = p;
if(auto s = w.lock()){
cout << *s;
}
Usato per evitare cicli di shared_ptr (tipico nel modello albero/grafo).
6️⃣ Controllare se un weak_ptr è valido
if(w.expired())
cout << "Oggetto non più valido";
7️⃣ Esempio completo
unique_ptr a = make_unique(10);
shared_ptr b = make_shared(20);
weak_ptr c = b;
cout << *a << ", " << *b;
LABORATORIO
Smart Pointer e Gestione Automatica della Memoria
In questo laboratorio imparerai a utilizzare gli smart pointer
unique_ptr, shared_ptr e weak_ptr
per gestire automaticamente oggetti dinamici, evitando memory leak
e semplificando il codice.
- Smart pointer: unique_ptr, shared_ptr, weak_ptr
- Funzioni: make_unique, make_shared
- Gestione automatica della memoria
1 Creare un unique_ptr
Crea un unique_ptr che memorizza un numero intero inserito dall utente.
unique_ptr p = make_unique(42);
cout << *p;
2 Trasferire il possesso
Trasferisci il contenuto da un unique_ptr a un altro.
unique_ptr a = make_unique(100);
unique_ptr b = move(a);
3 shared_ptr e contatore
shared_ptr s1 = make_shared(10);
shared_ptr s2 = s1;
cout << s1.use_count(); // 2
4 weak_ptr e controllo di validità
shared_ptr sp = make_shared(99);
weak_ptr wp = sp;
sp.reset(); // libera la memoria
if(wp.expired())
cout << "Oggetto scaduto";
5 Esercizi
- Gestisci un array dinamico usando
unique_ptr<int[]>. - Crea una funzione che restituisce un
shared_ptra un oggetto Persona. - Usa un
weak_ptrper monitorare un oggetto senza possederlo. - Simula un grafo con nodi che hanno puntatori deboli ai nodi vicini.