Allocazione dinamica delle variabili

Transcript

Allocazione dinamica delle variabili
Allocazione dinamica delle
variabili
• L'allocazione dello spazio di memoria occupato dalla
variabili puo' essere effettuata durante l'esecuzione del
programma.
Allocazione
dinamica delle
variabili
1
2
Allocazione statica
Allocazione dinamica
Nell'allocazione statica il programmatore dichiara il tipo
della variabile ed in caso di variabile vettoriale stabilisce
la dimensione del vettore.
Esempio
int vett[5];
Nell'allocazione dinamica il programmatore dichiara il
esclusivamente il tipo della variabile.
L'allocazione dello spazio di memoria per contenere la
variabile viene fatta durante l'esecuzione del
programma.
/* allocazione di un vettore di 5 interi */
Allocazione statica = allocazione effettuata all'atto della
compilazione.
L'accesso alle variabili dinamiche avviene attraverso il
loro indirizzo.
Esempio
int *vett;
/*
allocazione di un puntatore ad una
variabile di tipo intera */
3
Allocazione
4
malloc()
La creazione di una variabile dinamica avviene
prelevando dalla memoria un blocco di dimensione
opportuna tramite una funzione di allocazione (malloc).
Funzione appartenente alla libreria alloc.h che permette
di allocare memoria per le variabili dinamiche.
Prototipo della funzione:
void * malloc (unsigned int dimensione);
• la funzione restituisce un puntatore a void
(puntatore a memoria non strutturata). Per utilizzare
correttamente l'area allocata occorre effettuare
un'operazione di cast del puntatore verso il tipo di
dato a cui l'area e' destinata
• se il valore restituito dalla funzione e' NULL,
l'operazione di allocazione non ha avuto successo
(ad esempio per mancanza di memoria disponibile).
5
Maurizio Rebaudengo
6
1
malloc() (II)
Funzionamento
• Il parametro della funzione specifica la dimensione
(in numero di byte) della memoria da allocare.
• per scrivere codice portabile NON è opportuno
utilizzare valori interi costanti come parametri della
funzione malloc, ma è consigliabile utilizzare
l’operatore sizeof.
All’atto della chiamata della funzione di allocazione, il
sistema operativo cerca nell’area di memoria libera la
zona contigua di dimensione specificata dal parametro
della funzione.
Se l’area di memoria e’ disponibile, la funzione
restituisce il puntatore all’inizio della zona di memoria
allocata.
Se l’area di memoria non e’ disponibile, la funzione
restituisce il valore NULL.
7
…
Esempio
int dim;
8
Dichiarazione della variabile
puntatore
char *stringa;
…
All’atto della compilazione la variabile stringa viene
allocata per memorizzare un puntatore ad una area di
memoria che contiene una variabile di tipo char.
dim = 50;
stringa = (char *) malloc(sizeof(char) * dim);
if (stringa == NULL)
La variabile non viene inizializzata dunque non punta a
nessuna area di memoria.
{
Per accedere ad un’area di memoria occorre effettuare
un’allocazione dinamica attraverso la chiamata della
funzione malloc().
printf(“memoria non disponibile\n”);
return;
}
strcpy(stringa, “questa e’ una stringa”);
printf(“%s\n”, stringa);
…
9
10
Allocazione dinamica
Deallocazione
Dopo la chiamata della funzione malloc(), la variabile
puntatore contiene l’indirizzo di memoria dell’area
allocata.
Per liberare la memoria allocata dinamicamente, si
utilizza la funzione free().
stringa
q
u
e
s
t
a
e
Il blocco deallocato viene restituito all’area di memoria
libera e potrà essere riutilizzato successivamente
tramite eventuale chiamata a malloc.
stringa[0]
stringa[1]
stringa[2]
stringa[3]
stringa[4]
stringa[5]
stringa[6]
stringa[7]
Sintassi
void free (void *p)
• il parametro della funzione è un puntatore ad
un’area di memoria allocata tramite malloc().
11
Maurizio Rebaudengo
12
2
Esercizio
#include <stdio.h>
#include <alloc.h>
Si realizzi un programma in grado da leggere da file un
insieme di numeri interi.
void main()
Il numero di interi da leggere e’ scritto nella prima riga
del file.
{
FILE * finp;
int num_data;
int i;
int *vettore;
...
13
14
vettore = (int *) malloc(num_data*sizeof(int));
...
if (vettore == NULL)
finp = fopen("dati.dat", "r");
{
if (finp == NULL)
printf(“Errore in allocazione ‘vettore’\n”);
{
return;
printf("Errore nell'apertura del file \n");
return;
}
for (i = 0 ; i < num_data ; i++)
}
fscanf(finp,"%d", &vettore[i]);
else
free(vettore)
{
fclose(finp);
fscanf(finp, "%d", &num_data);
}
...
15
}
16
Esercizio
Soluzione
Si realizzi un programma per il caricamento della
classifica di un campionato di calcio. Il numero di
squadre e’ memorizzato nella prima riga del file.
#include <stdio.h>
typedef struct
{
char nome_sq[30];
int punti;
} classifica;
17
Maurizio Rebaudengo
18
3
main()
{
printf("\nIntroduci nome file: ");
classifica *vett_class;
scanf("%s", nomefile);
char nomefile[30];
int num_squadre;
num_squadre = carica_dati(nomefile, vett_class);
int carica_dati( char nomefile[],
classifica vett_class[]);
if (num_squadre)
int scrivi_dati( classifica vett_class[],
{
int num_squadre);
scrivi_dati(vett_class, num_squadre);
free(vett_class);
}
} /* end main */
19
20
int carica_dati(char nomefile[], classifica vett_class[])
{
int i, squadre=0, stato;
FILE *filedati;
for (i=0 ; i<squadre ; i++)
if ( (filedati = fopen(nomefile,"r")) == NULL)
fscanf(filedati,”%s %d”, vett_class[i].nome_sq,
{printf("Errore apertura: %s\n", nomefile);
&vett_class[i].punti);
return(0):
}
fclose(filedati);
else
}
{
return(squadre);
fscanf(filedati, “%d”, &squadre);
vett_class=(classifica *)malloc(squadre*sizeof(classifica));
}
if (vett_class== NULL)
{printf(“Errore in allocazione\n”);
return(0);
}
21
void
scrivi_dati(classifica
num_squadre)
vett_class[],
22
int
Esercizio
{
int indice;
printf("Squadra
Si memorizzi una insieme di stringhe di lunghezza
variabile in memoria minimizzando lo spazio di memoria
utilizzato.
Classifica\n");
for (indice = 0; indice < num_squadre; indice++)
{
Il numero di stringhe da memorizzare è scritto nella
prima riga del file.
printf("%-16s", vett_class[indice].nome_sq);
printf("
%d\n", vett_class[indice].punti);
}
return;
}
23
Maurizio Rebaudengo
24
4
Struttura dati
#include <stdio.h>
#include <alloc.h>
vettore
vettore[0]
c
a
s
c
i
vettore[1]
c
a
s
a
\0
n
a
\0
void main()
{
vettore[2]
vettore[3]
vettore[4]
FILE * finp;
vettore[5]
int num;
vettore[6]
char stringa[80];
vettore[7]
int i;
vettore[8]
vettore[9]
char ** vettore;
vettore[10]
...
vettore[11]
vettore[12]
25
26
...
vettore=(char **)malloc(num*sizeof(char *));
finp = fopen("stringa.dat", "r");
if (vettore == NULL)
if (finp == NULL)
{
{
printf(“Errore in allocazione ‘vettore’\n”);
printf("Errore nell'apertura del file\n");
return;
return;
}
}
for (i = 0 ; i < num ; i++)
else
{
{
fscanf(finp,"%s", stringa);
fscanf(finp, "%d", &num);
vettore[i]=(char *)
...
malloc(sizeof(char)*(strlen(stringa)+1));
...
27
28
if (vettore[i] == NULL)
{printf(“Errore in ‘vettore[%d]’\n”,i);
return;
}
strcpy(vettore[i], stringa);
}
for (i=0; i<num ; i++)
free(vettore[i]);
free(vettore)
fclose(finp);
}
}
29
Maurizio Rebaudengo
5