Sei sulla pagina 1di 14

Corso di Fondamenti di Informatica

Ingegneria delle Comunicazioni – BCOR


Ingegneria Elettronica – BELR

Introduzione al C

Unità 2 – Gestione Dinamica


della Memoria
D. Bloisi, A. Pennisi, S. Peluso, S. Salza
Esempio: puntatori “appesi”
Si consideri il seguente frammento di codice

int *pt1;
pt1 = malloc(sizeof(int));
*pt1 = 1;
printf("*pt1 = %d\n", *pt1);
int *pt2;
pt2 = pt1;
printf("prima di free(pt1)\n");
printf("*pt2 = %d\n", *pt2);
free(pt1);
printf("dopo di free(pt1)\n");
printf("*pt2 = %d\n", *pt2);
Puntatori - Unità 6 2013/2014 Pagina 2
Esecuzione: puntatori “appesi”
*pt1 = 1
prima di free(pt1)
*pt2 = 1
dopo di free(pt1)
*pt2 = 4001536

In questo caso, il rilascio della memoria puntata dalla


variabile pt1 lascia la variabile pt2 puntare ad una
locazione di memoria rilasciata e quindi suscettibile di
modifiche arbitrarie da parte del sistema operativo.
Questa situazione di puntatore appeso (dangling) è da
evitare assolutamente in quanto fonte di errori difficili da
individuare.
Puntatori - Unità 6 2013/2014 Pagina 3
Relazione tra array e puntatori (1/2)
In C il nome di un array è in realtà l’indirizzo
dell’elemento di indice 0.

int array[10];
printf("%p %p", array, &array[0]);

array e &array[0] hanno lo stesso valore.

printf("%p %p", array, &array[0]);


stampa 2 volte lo stesso indirizzo.

Array - Unità 7 2013/2014 Pagina 4


Relazione tra array e puntatori (2/2)
Possiamo assegnare l’indirizzo (del primo
elemento) di un array ad una variabile puntatore.

int arr[7];
int *pi;
pi = arr;

L’ultima istruzione è equivalente a


pi = &arr[0];

Array - Unità 7 2013/2014 Pagina 5


Creazione di un array con allocazione
dinamica
Invece di far puntare pi ad un vettore allocato attraverso
una dichiarazione (quindi statico, creato nello stack),
possiamo farlo puntare ad una zona di memoria allocata
dinamicamente (quindi nello heap):

int *pi, dim;


scanf("%d", &dim);
pi = malloc(dim * sizeof(int));
if(pi != NULL)
pi[dim-1] = 3; Assegno 3 alla cella di pi in
posizione dim-1!

Array - Unità 7 2013/2014 Pagina 6


Spiazzamento in un array
Allocazione statica Allocazione dinamica
! tipo* arr = !
tipo arr[N];!
!(tipo*)malloc(N*sizeof(tipo));!

Assegnazione di val alla


cella i dell’array arr!

arr[i] = val;! *(arr + i) = val;

Array - Unità 7 2013/2014 Pagina 7


Array come risultato di una funzione
La funzione copiaInversa prende come parametro un
array e restituisce un array con gli elementi in ordine
inverso, dall’ultimo al primo.
int* copiaInversa(int a[], int n) {
int* temp = (int*)malloc(n * sizeof(int));
if(temp != NULL) {
int i; cast
for (i = 0; i < n; i++) {
temp[n-1-i] = a[i];
}
}
return temp;
}
Array - Unità 7 2013/2014 Pagina 8
Esempio d’uso
int main () {
const int n = 5;
int x[n];
x[0] = 5; x[1] = 3; x[2] = 9; x[3] = 5; x[4] = 12;
int i;
for (i = 0; i < n; i++) // stampa 5 3 9 5 12
printf("%d ", x[i]);
printf("\n");
int * y = copiaInversa(x, n);
if(y == NULL) {
printf("ERRORE\n");
return(EXIT_FAILURE);
}
for (i = 0; i < n; i++) // stampa 12 5 9 3 5
printf("%d ", y[i]);
printf("\n");
free(y);
return(EXIT_SUCCESS);
} Array - Unità 7 2013/2014 Pagina 9
Nota

Il risultato di una funzione può essere un


riferimento ad un array, ma occorre usare
esplicitamente il puntatore, cioè non si può
scrivere int [] come risultato della funzione.

Array - Unità 7 2013/2014 Pagina 10


Nota
Array allocati staticamente non devono essere deallocati
esplicitamente. L’array x nell’esempio precedente sarà
deallocato automaticamente al termine del blocco
di codice in cui è definito (cioè nel main).

Invece, quando si alloca dinamicamente un array, al


termine del suo uso bisogna deallocare la memoria
occupata esplicitamente, tramite la funzione free.

Nell’esempio precedente:
free(y);

Array - Unità 7 2013/2014 Pagina 11


Matrici dinamiche
Allocazione di una matrice dinamica RxC di
elementi di tipo t!
t** M; //Puntatore a puntatore a t!
M = (t**) malloc(R*sizeof(t*));!
M[0] = malloc(C*sizeof(t));!
...!
M[R-1] = malloc(C*sizeof(t));!

Array - Unità 7 2013/2014 Pagina 12


Rappresentazione logica di matrici
dinamiche
M! M[0][0]! M[0][C-1]!
M[0]
!

M[R-1][0]! M[R-1][C-1]!

M[R-1]!

Array - Unità 7 2013/2014 Pagina 13


Matrici statiche vs. Matrici dinamiche
void f(int** A){!
!printf(“%d\n”, A[1]
[0]);!
}!
! Cosa stampa?
int main(){!
!int M[3][2];!
!M[1][0] = 5;!
!f(M);!
Attenzione:
}! le rappresentazioni delle matrici
statiche e dinamiche sono incompatibili!
Array - Unità 7 2013/2014 Pagina 14