Concetti Chiave
- L'allocazione dinamica della memoria viene eseguita durante l'esecuzione del programma, a differenza dell'allocazione statica che è stabilita dal compilatore.
- In C/C++, l'allocazione e deallocazione degli oggetti dinamici è gestita dal programmatore, sfruttando l'area di memoria chiamata heap.
- Le funzioni malloc() e calloc() sono utilizzate per allocare blocchi di memoria dinamica, restituendo un puntatore al blocco o NULL se non c'è memoria disponibile.
- La funzione free() rende nuovamente disponibile la memoria allocata, mentre realloc() consente di modificare la dimensione di un blocco di memoria esistente.
- Problemi comuni includono la produzione di spazzatura (garbage) e riferimenti fluttuanti (dangling references), che si verificano quando la memoria non viene gestita correttamente.
L’allocazione dinamica della memoria è l’allocazione eseguita durante l’esecuzione del pgm, in base ad esplicite istruzioni scritte nel pgm stesso.
Area di memoria: Heap
#define NULL 0 in
Operatore unario: sizeof(tipo|var) restituisce la dimensione in byte di un oggetto.
L’operatore sizeof, simile ad una funzione, ritorna un tipo speciale, usato per le dimensioni di memoria: size_t
In
Alloca un blocco di memoria di dim byte
Restituisce un puntatore generico al blocco di memoria (oppure NULL, se non c’è memoria disponibile).
Testare il puntatore (se uguale a NULL chiamare la exit() )
void * calloc (size_t num, size_t size);
Alloca num elementi consecutivi di memoria di dimensione size (inizializzandola a zero).
Serve ad allocare sequenze contigue di aree di memoria (array).
Restituisce un puntatore generico al blocco di memoria (oppure NULL, se non c’è memoria a disposizione).
double * punt, * punt2;
punt = (double *) calloc(10, sizeof(double));
Più interessante:
punt2 = (double *) calloc(var, sizeof(double));
Si può ottenere la stessa cosa anche con la malloc():
punt2 = (double *) malloc(var* sizeof(double));
Rende nuovamente disponibile lo spazio di memoria (il blocco di memoria) puntato da punt. Se punt è uguale a NULL, la free() non fa nulla.
E’ buona norma “azzerare” i puntatori sui quali è stata effettuata una free(), in modo che non puntino più all’area ora libera.
free(punt);
punt = NULL;
realloc()
void * realloc (void * punt, size_t newSize);
Cambia la dimensione (si può solo aumentarla) di un blocco di memoria
allocata.
Per maggiori informazioni consulta l’Help.
Ci sono due tecniche di recupero della memoria:
1) a carico del programmatore (Pascal, C, C++, …)
2) garbage collector (Lisp, Eiffel, Java, …)
C++
Operatori:
new
delete
delete [ ]
Esempi:
punt = new tipoDiDato;
delete punt;
puntVett = new tipoDiDato [const|var];
delete [ ] puntVett;
typedef struct{
char nome [21];
char cognome [25];
char indirizzo [30];
char professione [15];
}persona;
int main()
{
persona * p;
int i;
p=(persona *) malloc (numElem*sizeof(persona));
if(!p)
printf(“Memoria insufficiente\n”);
else
{
for(i=0; i
{
gets((p+i) nome);
….
}
}
}
Produzione di spazzatura (garbage)
Dangling references (riferimenti fluttuanti/pendenti)
Effetti collaterali
Se in una funzione, dopo aver allocato (nello stack) un puntatore e un’area dinamica (nello heap, assegnando al puntatore l’indirizzo dell’area), dimentichi di deallocare l’area prima che la funzione termini, produci garbage.
Un puntatore che punta a locazioni di memoria non significative prende il nome di dangling reference.
Domande da interrogazione
- Che cos'è l'allocazione dinamica della memoria?
- Quali sono le funzioni principali per l'allocazione dinamica in C/C++?
- Come si deallocano gli oggetti dinamici in C/C++?
- Quali problemi possono sorgere con l'uso dei puntatori in programmazione?
L'allocazione dinamica della memoria è l'allocazione eseguita durante l'esecuzione del programma, basata su istruzioni esplicite scritte nel programma stesso.
Le funzioni principali per l'allocazione dinamica in C/C++ sono malloc() e calloc(), che allocano blocchi di memoria e restituiscono un puntatore generico al blocco di memoria.
Gli oggetti dinamici in C/C++ si deallocano usando la funzione free(), che rende nuovamente disponibile lo spazio di memoria puntato dal puntatore.
I problemi principali con l'uso dei puntatori includono la produzione di spazzatura (garbage) e i riferimenti fluttuanti (dangling references), che si verificano quando un puntatore punta a locazioni di memoria non significative.