Linguaggio C++

Libreria Memory

Introduzione alla libreria memory del C++: smart pointer, gestione automatica della memoria, unique_ptr, shared_ptr, weak_ptr e laboratorio guidato.

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 PointerCaratteristicheDescrizione
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.


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_ptr a un oggetto Persona.
  • Usa un weak_ptr per monitorare un oggetto senza possederlo.
  • Simula un grafo con nodi che hanno puntatori deboli ai nodi vicini.