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
| Caratteristica | Stack | Heap |
|---|---|---|
| Gestione | Automatica (dal compilatore) | Manuale (new / delete) |
| Durata | Fino alla fine della funzione | Fino a quando non viene liberata |
| Velocità | Molto veloce | Più lenta |
| Dimensione | Limitata | Molto grande |
| Rischio | Stack overflow | Memory leak |
| Uso tipico | Variabili locali, parametri | Strutture 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.
- Ambiente C++ (Code::Blocks, Dev-C++, Visual Studio Code...)
- Console per osservare l output
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
deletee 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.