Linguaggio C++

Stack E Heap

Differenze tra stack e heap, gestione automatica e dinamica, con esempi pratici e laboratorio guidato.

Ogni programma in C++ utilizza due aree principali della memoria: lo stack e la heap. Capire la differenza tra queste due aree è fondamentale per scrivere programmi efficienti e privi di errori.


1️⃣ Lo Stack

Lo stack (pila) è gestito automaticamente dal compilatore. Contiene le variabili locali e i parametri delle funzioni. Quando una funzione termina, tutta la memoria che aveva allocato nello stack viene automaticamente liberata.

void funzione() {
    int a = 10;
    int b = 20;
    cout << a + b;
} // alla fine, 'a' e 'b' vengono distrutte automaticamente

Ogni chiamata di funzione crea un nuovo “frame” nello stack. Quando la funzione termina, il frame viene rimosso.

⚠️ Lo stack è veloce ma limitato: usare troppa memoria (ad esempio con array molto grandi) può causare uno stack overflow.

int v[10000000]; // troppo grande per lo stack → errore

2️⃣ La Heap

La heap (memoria dinamica) è gestita manualmente dal programmatore. Serve per creare variabili o strutture dati durante l esecuzione del programma, quando non si conoscono a priori le dimensioni o la durata.

int* p = new int;  // alloca memoria dinamica
*p = 50;           // assegna un valore
cout << *p;        // stampa 50
delete p;          // libera la memoria

👉 A differenza dello stack, la heap non si svuota da sola: bisogna usare delete o delete[] per liberare la memoria.


3️⃣ Array dinamici nello heap

La heap è indispensabile per creare strutture dati la cui dimensione viene decisa a runtime.

int n;
cout << "Quanti numeri vuoi inserire? ";
cin >> n;

int* v = new int[n]; // array di dimensione dinamica

for (int i = 0; i < n; i++) {
    cout << "Inserisci numero: ";
    cin >> v[i];
}

delete[] v; // libera tutta la memoria dell array

4️⃣ Differenze principali

CaratteristicaStackHeap
GestioneAutomatica (dal compilatore)Manuale (new / delete)
DurataFino alla fine della funzioneFino a quando non viene liberata
VelocitàMolto velocePiù lenta
DimensioneLimitataMolto grande
RischioStack overflowMemory leak
Uso tipicoVariabili locali, parametriStrutture dinamiche (liste, alberi...)

5️⃣ Riepilogo visivo

int main() {
    int a = 10;           // variabile nello stack
    int* p = new int(20); // variabile nello heap
}

Memoria del programma:


STACK                      HEAP
------                     -----
a = 10                     [20]  ← creato da new
p → indirizzo ----------→

Quando il programma termina:

  • lo stack si libera automaticamente;
  • la heap resta occupata finché non viene chiamato delete.
LABORATORIO

Stack e Heap in Azione

In questo laboratorio osserverai la differenza tra variabili allocate nello stack e nella heap, e capirai perché è importante liberare la memoria dinamica.


1 Variabili nello stack

Dichiara due variabili locali dentro una funzione e osserva come vengono distrutte al termine.

void funzione() {
    int a = 5;
    int b = 10;
    cout << "Somma: " << a + b << endl;
}

2 Allocazione nello heap

Usa new per creare una variabile in memoria dinamica e delete per liberarla.

int* p = new int;
*p = 42;
cout << *p << endl;
delete p;

3 Array dinamico

Chiedi all utente quanti numeri inserire e crea un array dinamico per memorizzarli.

int n;
cout << "Quanti numeri vuoi inserire? ";
cin >> n;
int* v = new int[n];
for (int i = 0; i < n; i++) {
    cout << "Numero " << i+1 << ": ";
    cin >> v[i];
}
delete[] v;

4 Approfondimenti

  • Stampa gli indirizzi di memoria delle variabili nello stack e nella heap per confrontarli.
  • Prova a dimenticare il delete e osserva che il programma funziona, ma la memoria non viene liberata.
  • Disegna uno schema che rappresenti la crescita dello stack e l uso della heap.