Fondamenti 2024-2025: Allocazione dinamica della memoria in C++

Slide dall'Università sui Fondamenti 2024-2025: Allocazione dinamica della memoria in C++. Il Pdf esplora l'allocazione dinamica della memoria in C++, contrapponendola a quella statica, con esempi pratici di riallocazione di array e gestione di strutture dati, utile per Informatica.

Mostra di più

21 pagine

Fondamenti 2024-2025 - Secondo
semestre
17/03/2025
1
Allocazione dinamica
In C++ lo spazio di memoria occupato da una
variabile (ad esempio un array) deve essere
noto a priori, ovvero in fase di compilazione.
Tale meccanismo prende il nome di
allocazione statica della memoria.
Non sempre, tuttavia è possibile stabilire a
priori le dimensioni delle strutture dati.
In C++ è possibile allocare memoria anche
dinamicamente, ovvero durante l’esecuzione di
un programma (allocazione dinamica).
L’accesso alla memoria allocata in modo
dinamico avviene tramite puntatori.
Quando può essere utile
Quasi tutti i banchi di dati non hanno a
priori noto il numero degli elementi:
- registro delle macchine dei genovesi,
- oggetti in vendita in un negozio,
- studenti dell'università,
….
Anche il nostro registro di film
158
159
Fondamenti 2024-2025 - Secondo
semestre
17/03/2025
2
Allocazione dinamica
Il sistema operativo assegna ai programmi
specifici segmenti della memoria primaria:
Il code segment ospita le istruzioni del programma;
Il data segment ospita costanti e variabili che
esistono durante l’intera esecuzione del
programma (ad esempio variabili globali);
Lo stack contiene le variabili locali, i parametri delle
funzioni e le copie dei registri per restituire il
controllo alle funzioni chiamanti al termine delle
funzioni chiamate;
La heap viene utilizzata per l’allocazione dinamica
delle variabili.
Allocazione dinamica
Indirizzi di memoria “alti”
Stack
Heap
Data segment
Indirizzi di memoria “bassi”
Code segment
L'organizzazione della memoria dipende dal
computer e dal sistema operativo. Solitamente,
gli indirizzi dello stack decrescono, mentre gli
indirizzi dell'heap crescono
160
161

Visualizza gratis il Pdf completo

Registrati per accedere all’intero documento e trasformarlo con l’AI.

Anteprima

Allocazione dinamica

Fondamenti 2024-2025 - Secondo semestre 17/03/2025 Allocazione dinamica

  • In C++ lo spazio di memoria occupato da una variabile (ad esempio un array) deve essere noto a priori, ovvero in fase di compilazione.
  • Tale meccanismo prende il nome di allocazione statica della memoria.
  • Non sempre, tuttavia è possibile stabilire a priori le dimensioni delle strutture dati.
  • In C++ è possibile allocare memoria anche dinamicamente, ovvero durante l'esecuzione di un programma (allocazione dinamica).
  • L'accesso alla memoria allocata in modo dinamico avviene tramite puntatori.

158

Quando può essere utile

  • Quasi tutti i banchi di dati non hanno a priori noto il numero degli elementi:
    • registro delle macchine dei genovesi,
    • oggetti in vendita in un negozio,
    • studenti dell'università,
  • Anche il nostro registro di film

159 1Fondamenti 2024-2025 - Secondo semestre 17/03/2025 Allocazione dinamica

  • Il sistema operativo assegna ai programmi specifici segmenti della memoria primaria:
    • Il code segment ospita le istruzioni del programma;
    • Il data segment ospita costanti e variabili che esistono durante l'intera esecuzione del programma (ad esempio variabili globali);
    • Lo stack contiene le variabili locali, i parametri delle funzioni e le copie dei registri per restituire il controllo alle funzioni chiamanti al termine delle funzioni chiamate;
    • La heap viene utilizzata per l'allocazione dinamica delle variabili.

160

Organizzazione della memoria

Allocazione dinamica Stack Indirizzi di memoria "alti" … Heap Data segment L'organizzazione della memoria dipende dal computer e dal sistema operativo. Solitamente, gli indirizzi dello stack decrescono, mentre gli indirizzi dell'heap crescono Code segment Indirizzi di memoria "bassi" 161 2Fondamenti 2024-2025 - Secondo semestre 17/03/2025

Esperimento 1: Variabili globali e locali

int a=0; int b=0; float f=0; Esperimento 1 int main() { int c=0; int d=0; float g=0; cout << "variabili globali" << endl; cout << &a << endl; cout << &b << endl; cout << &f << endl; variabili globali 0x407030 0x407034 0x407038 Data segment variabili locali cout << "variabili locali" << endl; 0x61fe34 0x61fe30 Stack cout << &c << endl; cout << &d << endl; cout << &g << endl; return 0; E222 Provate adesso sui vostri laptop! 162

Operatore new

  • L'operatore new alloca dinamicamente nella heap un'area di memoria atta a contenere un oggetto del tipo specificato e ritorna un puntatore a tale area di memoria.
  • Sintassi: new tipo ; new tipo [ dimensione] ; (per gli array)

163 3

0x61fe2c Process returned 0 (0x0) Press any key to continue. execution time : 1.131 s }

Esempio di allocazione con new

Fondamenti 2024-2025 - Secondo semestre 17/03/2025 Esempio int* p; p = new int; *p=10; heap p · dichiaro un puntatore · allocco nella heap lo spazio per un intero, cioè 4 byte . creo una zona di memoria che può contenere un intero · operatore new restituisce un puntatore che viene assegnato a p · attraverso il puntatore p posso accedere questo spazio di memoria e posso memorizzare un numero intero . In pratica, per i tipi semplici all. dinamica viene utilizzata raramente. Perché? 164 Esempio int* p; p = new int; *p=10; int+ pi *p=10; · dichiaro un puntatore · allocco nella heap lo spazio per un intero, cioè 4 byte · creo una zona di memoria che può contenere un intero · operatore new restituisce un puntatore che viene assegnato a p · attraverso il puntatore p posso accedere questo spazio di memoria e posso memorizzare un numero intero . In pratica, per i tipi semplici all. dinamica viene utilizzata raramente. Perché? 165 4Fondamenti 2024-2025 - Secondo semestre 17/03/2025

Esperimento 2: Allocazione dinamica

int a=0;int b=0; float f=0; Esperimento 2 int main() { int c=0; int d=0; float g=0; cout << "variabili globali" << endl; variabili globali 0x407030 Data segment cout << &a << endl << &b << endl << &f << endl cout << "variabili locali" << endl; 0x407034 0x407038 cout << &c << endl << &d << endl << &g << endvariabili locali 0x61fe4c 0x61fe48 0x61fe44 allocazione dinamica 0xf31760 0xf31780 Heap 0xf31ad0 cout << "allocazione dinamica " << endl cout << p << endl; cout << q << endl; cout << r << endl; altre variabili locali 0x61fe38 0x61fe30 Stack 0x61fe28 Process returned 0 (0x0) Press any key to continue. execution time : 0.435 s cout << "altre variabili locali" << endl; cout << &p << endl; cout << &q << endl; cout << &r << endl; wooclap return 0; Codice evento GQLROF } E222 Provate adesso sui vostri laptop! 166

- * P men inti HEAD Cout << Pt STACK Toutes & pG 0 167 5

1 Stack int *p = new int; int *q = new int; float *r = new float;

Esempio di allocazione dinamica di stringhe

17/03/2025 Fondamenti 2024-2025 - Secondo semestre Esempio più interessante char* stringa; stringa = new char [30] ; heap stringa · dichiaro un puntatore ad un char · allocco nella heap lo spazio per 30 caratteri · operatore new restituisce un puntatore che viene assegnato a stringa · attraverso il puntatore stringa posso accedere questo spazio di memoria e posso memorizzare una sequenza di 30 caratteri 169

Operatore new: dimensione a run-time

Operatore new · La dimensione dell'area di memoria da allocare si può definire a run-time. Ad esempio: int n; cout << "Inserire le dimensioni di una stringa"; cin >> n; char* stringa = new char [n] ; if (stringa != 0) cin >> stringa; · Nota: se la memoria disponibile è esaurita, new restituisce un puntatore nullo. Prima di de-referenziare il puntatore restituito da new, occorre quindi assicurarsi che sia valido! 170 6Fondamenti 2024-2025 - Secondo semestre 17/03/2025

Deallocazione

Meccanismo di deallocazione

Deallocazione · Un oggetto allocato dinamicamente resta allocato finché: - Non viene esplicitamente deallocato; - Il programma non termina. · In C++ non esiste un meccanismo automatico per recuperare la memoria allocata e non più utilizzata (garbage collection). · Pertanto, la memoria inutilizzata, ma non esplicitamente deallocata di norma non è più disponibile! 171

Operatore delete

Operatore delete · L'operatore delete dealloca l'area di memoria, precedentemente allocata in modo dinamico, puntata da un puntatore: · Sintassi: delete puntatore ; delete [] puntatore; (per gli array) · Esempio: int *p; char *stringa; p = new int; stringa = new char [30] ; delete p; delete [] stringa; 172 717/03/2025 Fondamenti 2024-2025 - Secondo semestre

Vantaggi dell'allocazione dinamica

Vantaggi allocazione dinamica · Il meccanismo di allocazione e deallocazione dinamica della memoria consente: - La gestione efficiente delle risorse di memoria in modo da allocare solo lo spazio realmente necessario; - La creazione di strutture dati fatte da un numero di elementi che possono variare durante l'esecuzione del programma. · Occorre tuttavia usare con attenzione gli operatori new e delete! 173

Esempio 1: allocazione dinamica di array

Esempio 1: allocazione dinamica di array #include <iostream> using namespace std; int main() { int n; cout << "Inserire il numero di elementi: "; 1000 cin >> n; if (n <= 0) return -1; int* a = new int [n] ; if (a == 0) return -1; for (int i = 0; i < n; i++) a[i] = i + 1; for (int j = 0; j < n - 1; j++) cout << a[j] << ", "; cout << a[n - 1] << endl; delete [] a; return 0; } E037 174

Esempio 2: allocazione dinamica di stringhe

817/03/2025 Fondamenti 2024-2025 - Secondo semestre Esempio 2: allocazione dinamica di stringhe #include <iostream> #include <cstring> using namespace std; int main () { 0000000 char s1[256]; char s2[256]; char* ps3; cout << "Inserire due stringhe: "; cin >> s1 >> s2; int dim1 = strlen (s1) ; int dim2 = strlen (s2) ; ps3 = new char [dim1+dim2+1] ; //allocazione if (ps3 == 0) return -1; strcpy (ps3, s1) ; strcat(ps3, s2); cout << "Stringa concatenata: " << ps3 << endl; delete [] ps3; //deallocazione return 0; } E038 175

Commento su delete

Commento su delete · Libera la memoria allocata dinamicamente in modo che possa essere riallocata mediante successive chiamate dell'operatore new · Questo rende riutilizzabile la memoria puntata, ma non cancella il puntatore che può essere riutilizzato per puntare ad un'altra variabile successivamente allocata con new 176

Allocazione di diverse aree con lo stesso puntatore

917/03/2025 Fondamenti 2024-2025 - Secondo semestre Allocazione di diverse aree con lo stesso puntatore 9000000 int main() { int* a; for (int k = 0; k < 10000; k++) { a = new int[k]; · Posso usare lo stessa variabile di puntatore per allocare vari spazi nella memoria if (a == NULL) { · In questo codice c'è un errore. Dove? cout << "Memory allocation failed." << endl; return -1; } for (int i = 0; i < k; i++) a[i] = i + 1; for (int j = 0; j < k; j++) cout << a[j] << ", " } delete[] a; return 0; ? · Controllare l'uso della memoria nel Task Manager } E039 177 Allocazione di diverse aree con lo stesso puntatore 00 int main() { int* a; for (int k = 0; k < 10000; k++) { a = new int[k]; · Posso usare lo stessa variabile di puntatore per allocare vari spazi nella memoria if (a == NULL) { cout << "Memory allocation failed." << endl; return -1; } for (int i = 0; i < k; i++) a[i] = i + 1; for (int j = 0; j < k; j++) cout << a[j] << ", "; } · In questo codice c'è un errore. Dove? delete[] a; return 0; } E039 · Controlla l'uso della memoria nel Task Manager 178

Versione corretta dell'allocazione con lo stesso puntatore

1017/03/2025 Fondamenti 2024-2025 - Secondo semestre Allocazione di diverse aree con lo stesso puntatore int main() { int* a; • Versione corretta: for (int k = 0; k < 10000; k++) { a = new int[k]; if (a == NULL) { · in ogni ciclo di for, operatore delete dovrebbe liberare la memoria allocata con new cout << "Memory allocation failed." << endl; return -1; } for (int i = 0; i < k; i++) a[i] = i + 1; for (int j = 0; j < k; j++) cout << a[j] << ", "; delete[] a; } return 0; } · Ricontrolla l'uso della memoria nel Task Manager 179

Strutture statiche vs dinamiche

Le strutture statiche Vs dinamiche const int n = 4; int a[n]; int *p; int n = 0; cin>>n; p = new int [n]; Strutture dinamiche, p.e., liste (vedremmo a maggio) • Non posso cambiare le dimensioni di a dopo la compilazione del programma · Una volta deciso il valore di n durante l'esecuzione del programma, non è più possibile modificare le dimensioni dell'array a cui punta p • è sempre possibile aggiungere nuovi elementi, · l'unico limite è la memoria disponibile. · Posso effettuare una riallocazione dinamica: – creo un nuovo array con n+1 elementi, – copio tutti gli elementi, cancello il vecchio array. – maggiore flessibilità 180

Esempio di riallocazione

1117/03/2025 Fondamenti 2024-2025 - Secondo semestre Esempio di riallocazione int main() { int* array = new int[3];// Allocazione iniziale per un array di 3 int for (int i = 0; i < 3; ++i) array[i] = i * 10; // Inizializzazione ... int* newArray = new int [5]; // Riallocazione per un array di 5 interi // Copia dei valori dall'array originale al nuovo array for (int i = 0; i < 3; ++i) newArray[i] = array[i] ; delete[] array; // Deallocazione della memoria dell'array originale // Aggiunta di valori aggiuntivi al nuovo array for (int i = 3; i < 5; ++i) newArray[i] = i * 10; for (int i = 0; i < 5; ++i) cout << newArray[i] << " "; //stampa tutto delete[] newArray; // Deallocazione della memoria del nuovo array return 0; } E069 181 Esempio di riallocazione int main() { E069 int* array1 = new int [3]; for (int i = 0; i < 3; ++i) array1[i] = i * 10; // Inizializzazione cout << "Valori del array prima di riallocazione:" << endl; for (int i= 0; i < 3; ++i) cout << array1[i] << " "; cout << endl; int* newArray = new int[5]; // Riallocazione per un array di 5 interi for (int i = 0; i < 3; ++i) newArray[i] = array1[i]; //Copia dei valori delete[] array1; // Deallocazione della memoria dell'array originale array1=newArray; for (int i = 3; i < 5; ++i) array1[i] = i * 10; // Aggiunta di valori cout << "Valori del nuovo array dopo la riallocazione:" << endl; for (int i= 0; i < 5; ++i) cout << array1[i] << " "; delete[] array1; // Deallocazione della memoria del nuovo array return 0; } 9000000 182 12

Non hai trovato quello che cercavi?

Esplora altri argomenti nella Algor library o crea direttamente i tuoi materiali con l’AI.