Sei sulla pagina 1di 16

Corso di Fondamenti di Informatica

Ingegneria delle Comunicazioni – BCOR


Ingegneria Elettronica – BELR

Introduzione al C

Unità – Gestione Dinamica della


Memoria
D. Bloisi, A. Pennisi, S. Peluso, S. Salza
Gestione dinamica della memoria
Nell’ Unità 5 è stato presentato il modello di allocazione
della memoria tramite stack, che si basa sulle regole di
campo d’azione (definito staticamente, cioè al momento
della compilazione).

Attraverso i puntatori, il C permette di utilizzare un altro


modello di allocazione della memoria, che consente di
definire la memoria dinamicamente, cioè al momento
dell’ esecuzione del programma.

Questa possibilità risulta particolarmente utile ed


importante quando non sono note o prevedibili a priori
le dimensioni dei dati in ingresso ad un programma.
Puntatori - Unità 6 2013/2014 Pagina 2
Allocazione dinamica della memoria
Durante l’esecuzione, un programma può
richiedere esplicitamente uno spazio di memoria
per immagazzinare dati.
Allo stesso modo, può richiedere di rilasciare tale
spazio quando non sarà più necessario.

Il C offre la funzione malloc per riservare


(allocare) uno spazio di memoria e la funzione
free per rilasciare (deallocare) memoria.

Insieme all’operatore sizeof sono essenziali per


l’allocazione dinamica della memoria.
Puntatori - Unità 6 2013/2014 Pagina 3
Funzione malloc!
La funzione malloc permette di allocare dinamicamente
una porzione (chunk) di memoria.

void *malloc( size_t size );

Restituisce un puntatore alla porzione di memoria di


dimensione size oppure NULL se si è verificato un
errore.
E’ definita nella standard library - va inserita la direttiva
#include <stdlib.h>

size_t è definito come il tipo intero senza segno


restituito dall’operatore sizeof
Puntatori - Unità 6 2013/2014 Pagina 4
Esempio su malloc!
int *p;
• crea in memoria una variabile di tipo puntatore a int

p = malloc(sizeof(int));
• crea in memoria una variabile di tipo int
• restituisce l’indirizzo della variabile creata (primo byte)
• assegna l’indirizzo restituito a p

*p = 7;
• la variabile di tipo int creata assume il valore 7

printf("%d", *p);
• viene stampato a video 7
Puntatori - Unità 6 2013/2014 Pagina 5
Modello di allocazione dinamica
L’allocazione dinamica della memoria avviene nello heap.
Se lo spazio di memoria allocabile dinamicamente è esaurito viene
restituito il puntatore NULL.

int *pt1; // dichiarazione del puntatore ad int


pt1 = malloc(sizeof(int)); // creazione dinamica
// della variabile int
if (pt1 == NULL) {
printf("allocazione fallita\n");
exit(EXIT_FAILURE);
}

In caso di mancanza di memoria il programma termina con l’istruzione


exit(EXIT_FAILURE); che notifica il fallimento.

Puntatori - Unità 6 2013/2014 Pagina 6


Funzione free!
La funzione free permette di deallocare la memoria
allocata dinamicamente.

void free( void* ptr );

free dealloca lo spazio puntato da ptr, rendendolo


disponibile per usi futuri.

Nota: ptr deve essere stato usato in una chiamata


precedente a malloc()

E’ definita nella standard library (<stdlib.h>)

Puntatori - Unità 6 2013/2014 Pagina 7


Esempio free!
#include <stdio.h>
#include <stdlib.h>

int main() {
int *p;
double *d;
p = malloc(sizeof(int));
*p = 7;
printf("%d", *p);
free(p);
d = malloc(sizeof(double));
*d = 7;
printf(" %f", *d);
free(d);
}
Puntatori - Unità 6 2013/2014 Pagina 8
Tempo di vita delle variabili allocate
dinamicamente (1/2)
Per le variabili allocate dinamicamente il tempo
di vita corrisponde al periodo che va
Ø  dal momento in cui la variabile viene allocata
Ø  al momento in cui la variabile viene deallocata.

Il tempo di vita di una variabile allocata


dinamicamente è definito solo al momento
dell'esecuzione del programma.

Puntatori - Unità 6 2013/2014 Pagina 9


Tempo di vita delle variabili allocate
dinamicamente (2/2)
Se una variabile allocata dinamicamente non è
deallocata esplicitamente, il suo tempo di vita si
prolunga fino alla terminazione del programma.

Può verificarsi il caso in cui una zona di memoria


allocata non sia più accessibile, in quanto non ci
sono variabili che la “riferiscono”.
Tale zona di memoria rimarrà inutilmente
occupata per tutta la durata del programma.
Memory Leak!
Puntatori - Unità 6 2013/2014 Pagina 10
Esempio: tempo di vita variabili
dinamiche
int* creaint(int a) {
int* temp = malloc(sizeof(int));
*temp = a;
return temp;
}

int main() {
int* pt2 = creaint(5);
printf("*pt2 = %d\n", *pt2);
}

Puntatori - Unità 6 2013/2014 Pagina 11


Esecuzione: tempo di vita variabili
dinamiche
Il programma precedente stampa
*pt2 = 5
poiché la variabile allocata dalla funzione
creaint viene restituita al programma principale
e rimane accessibile anche al termine della
esecuzione della funzione.

Le variabili create dinamicamente non rispettano


le regole di campo di azione.

Puntatori - Unità 6 2013/2014 Pagina 12


Esempio: esaurimento della memoria

int *temp, k;
for (k = 1; 1 ; k++) {
printf("k = %d\n", k);
temp = malloc(sizeof(int));
}

L'esecuzione comporta una richiesta infinita di


memoria (si noti che la condizione del ciclo è
sempre verificata).

Puntatori - Unità 6 2013/2014 Pagina 13


Esecuzione: esaurimento della
memoria

L’esecuzione produrrà una richiesta infinita di


memoria che in C comporta (dopo un numero di
cicli piuttosto alto) l’interruzione dell’esecuzione
con un messaggio simile al seguente:

dynamic(1320) malloc: *** mmap(size=16777216) failed


(error code=12) *** error: can’t allocate region

Puntatori - Unità 6 2013/2014 Pagina 14


Problemi di deallocazione della
memoria

int *pt1;
pt1 = malloc(sizeof(int)); // allocazione della variabile
*pt1 = 1;
printf("*pt1 = %d\n", *pt1); // uso della variabile
free(pt1);
// la locazione di memoria rimane accessibile dopo free!!!
printf("after free\n");
printf("*pt1 = %d\n", *pt1);
// la stessa locazione di memoria potrebbe essere ri-allocata!!!
int *pt2 = malloc(sizeof(int));
printf("after malloc\n");
printf("*pt2 = %d\n", *pt2);

Puntatori - Unità 6 2013/2014 Pagina 15


Discussione: problemi di
deallocazione della memoria
In questo caso, può verificarsi che la memoria rimanga
accessibile anche dopo il rilascio ed addirittura che il suo
contenuto sia ancora immutato (anche se non è garantito).

In aggiunta, la riallocazione immediata potrebbe riallocare


la variabile nella stessa posizione della memoria e quindi
con lo stesso valore (anche questo non è garantito).

In ogni caso, entrambe le situazioni sopra delineate sono


da evitare accuratamente, in quanto fonti di errori e di
comportamenti instabili del programma.

Puntatori - Unità 6 2013/2014 Pagina 16

Potrebbero piacerti anche