La Durata di Archiviazione (Storage Duration)
“Things you used to own, now they own you.” — Chuck Palahniuk, Fight Club
Il ciclo di vita di un oggetto è la serie di stadi che un oggetto C++ attraversa durante la sua esistenza. Tutto ruota attorno all’allocazione e deallocazione della memoria. A differenza di linguaggi con Garbage Collector (come Java o C#), in C++ la gestione delle risorse non è magica: è compito del programmatore plasmare e comprendere la durata degli oggetti (Storage Duration).
Ogni oggetto attraversa queste fasi:
- Allocazione della memoria e inizio della storage duration.
- Chiamata al costruttore (inizio della lifetime vera e propria).
- Utilizzo nel programma.
- Chiamata al distruttore (fine della lifetime).
- Deallocazione della memoria (fine della storage duration).
Durata di Archiviazione Automatica
Section titled “Durata di Archiviazione Automatica”Un oggetto automatico viene allocato all’inizio del blocco di codice in cui risiede (il suo scope) e viene deallocato alla fine dello stesso. I parametri delle funzioni e le variabili locali sono oggetti automatici.
void power_up(int amount) { int local_var = 0; // amount e local_var sono variabili automatiche. // Smetteranno di esistere appena la funzione finisce.}Durata di Archiviazione Statica
Section titled “Durata di Archiviazione Statica”Un oggetto statico (dichiarato con static o extern al di fuori di una funzione, o come variabile globale) viene allocato all’inizio del programma e deallocato alla fine. La sua esistenza copre l’intero tempo di esecuzione.
L’uso di static in contesti globali impone anche l’Internal Linkage, ovvero rende la variabile inaccessibile dagli altri file sorgenti (translation units) del progetto. Per avere visibilità su tutto il progetto (External Linkage), si usa la keyword extern.
Membri Statici di una Classe
Section titled “Membri Statici di una Classe”I membri di una classe solitamente muoiono con l’oggetto che li contiene. I membri statici, invece, non sono associati a una singola istanza della classe ma appartengono alla classe in sé, e ne esiste sempre e solo una singola copia condivisa da tutte le istanze. Essi hanno durata di archiviazione statica.
Durata Thread-Local
Section titled “Durata Thread-Local”Quando si scrivono programmi concorrenti (multi-thread), le variabili globali mutabili sono fonte di infiniti problemi (race conditions). Se anteponiamo thread_local, creiamo una variabile la cui durata è limitata alla vita del singolo thread, garantendo che ogni thread abbia la propria istanza indipendente e isolata della variabile.
Durata di Archiviazione Dinamica
Section titled “Durata di Archiviazione Dinamica”La durata dinamica è quella su cui hai controllo manuale completo: sei tu a dire quando allocare la risorsa e quando distruggerla. Avviene tramite la keyword new per allocare e delete per deallocare.
Da un grande potere derivano immensi problemi:
- Memory Leaks: Se ti dimentichi di chiamare
delete, la memoria non verrà mai restituita al sistema fino al riavvio/chiusura del processo. - Use After Free: Se usi un puntatore su cui è già stata chiamata
delete, stai leggendo/scrivendo “nel vuoto”. Ciò causa corruzione della memoria e vulnerabilità di sicurezza.