# Gestione della memoria in C++ La memoria di un processo in un sistema operativo è divisa in diverse aree o segmenti, ognuna delle quali ha uno scopo specifico. Le quattro principali aree di memoria in un processo sono: ### Stack: * Lo stack è una regione di memoria utilizzata per la gestione delle chiamate di funzione e delle variabili locali. * Le variabili locali e i dati di controllo, come gli indirizzi di ritorno delle funzioni, vengono memorizzati nello stack. * L'allocazione e la deallocazione della memoria nello stack sono gestite automaticamente dal compilatore e dal sistema operativo. * Il formato di accesso dello stack è di tipo "last in, first out" (LIFO), il che significa che l'ultimo elemento inserito è il primo a essere rimosso. ### Heap: * L'heap è una regione di memoria utilizzata per l'**allocazione dinamica** di dati a lungo termine. * In questa area, vengono allocate e deallocate strutture dati come gli oggetti o le strutture di dati complesse a cui si fa riferimento tramite puntatori. * La gestione della memoria nell'heap richiede una maggiore attenzione da parte del programmatore, poiché è necessario **allocare** e **liberare** la **memoria manualmente** per evitare perdite di memoria (memory leaks) o accessi errati. ### Static: * L'area statica è destinata a variabili e dati statici. * Questa regione di memoria contiene variabili globali e variabili statiche locali, che vengono allocate una sola volta all'inizio dell'esecuzione del programma e mantengono il loro valore per tutto il ciclo di vita del processo. * L'accesso a queste variabili è possibile in qualsiasi momento durante l'esecuzione del programma. ### Text o codice: * L'area text contiene il **codice eseguibile del programma**. * Questa parte della memoria contiene le istruzioni binarie del programma, e il sistema operativo non consente di scrivere direttamente in questa area. Quindi Il programmatore non **ha accesso** a questa parte della memoria * Le istruzioni vengono eseguite dalla CPU direttamente dalla memoria text. <!-- | Memoria del processo | | | :---- | :---- | | Heap | Memoria dinamica | | Stack | Variabili delle funzioni | | Static/Global | Variabili globali (visibili da tutto il programma) | | Codice | Istruzioni del programma (binarie) | --> ![alt text](/resources/programmazione-c++/immagini/memory.png) ## Esempio Prendiamo in considerazione il seguente pezzo di codice: ```cpp #include <iostream> using namespace std; int base = 7; int potenza(int b, int e){ int r = 1; for(int i=0; i<e; i++){ r = r * b; // eseguo l'operazione di elevazione a potenza } return r; // restituisco il risultato } int main() { int esponente; cin >> esponente; int risultato = potenza(base, esponente); cout << "Il risultato è: "<<risultato<<endl; return 0; } ``` Capiamo ogni variabile in quale parte della memoria viene allocata: * **Globale** (statico o dati), contiene le variabili globali, ovvero quelle create all'esterno delle funzioni Nel caso in esempio c'è una sola variabile globale `int base` che è visibile ed utilizzabile in qualunque parte del programma. La sua dichiarazione infatti viene effettuata fuori dalle funzioni, all'inizio del codice. * **Stack**, contiene le variabili interne alle funzioni, compresi i parametri di queste. Nel caso in esempio ci sono 6 variabili allocate nello stack. In ordine di allocazione troviamo: - `int esponente` e `int risultato` create nel main - `int b`, `int a`, `int r` create nel momento in cui viene svolta la funzione `potenza` - `int i` che esiste solamente nell'intervallo di tempo nel quale viene svolto il ciclo for. * **Heap**, contiene le variabili create dinamicamente, in questo esempio di codice non viene utilizzata. <im> Per “variabili create dinamicamente” si intendono variabili dichiarate dinamicamente, non assegnate dinamicamente. </im> * **Text**, contiene il codice c++ convertito in linguaggio macchina. Un esempio potrebbe essere il seguente: ![](/resources/programmazione-c++/immagini/assembly.png)