Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà...

24
Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dell’Insubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2007/08

Transcript of Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà...

Page 1: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

Laboratorio di Linguaggi

lezione VII: puntatori 3/3

Marco Tarini

Università dell’Insubria

Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese

Corso di Laurea in Informatica

Anno Accademico 2007/08

Page 2: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Assegnare i Puntatori

• In memoria, un puntatore è un indirizzo– (...di una variabile)– (...di cui e' noto il tipo)

• Bene, ma quale indirizzo?

– Modo 1: prendere l'indirizzo di una variabile esistente• il puntatore punterà a quella variabile

– Modo 2: allocare (riservare, prenotare) della memoria libera

• il puntatore punterà ad una nuova variabile, memorizzata nella memoria così riservata

• la nuova variabile è allocata dinamicamente!

Page 3: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione

void* malloc(unsigned int n);

funzione malloc ( sta per memory allocation )

1 - alloca n bytes di memoria.

2 - restituisce l' indirizzo della memoria appena allocata

• sotto forma di puntatore generico !

• " " puntatore generico, puntatore senza tipo, in pratica, un semplice indirizzo di memoria

void*

Page 4: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione: esempio

int* p;p = malloc( ? );

Ma il tipo non torna!

A sx abbiamo un (int*) mentre a dx un (void*)

Avviene un Typecast fra puntatori

int* p;p = (int*) malloc(4);

Possiamo anche renderlo esplicito (meglio):

4

Page 5: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Typecast fra puntatori

• Ogni tipo puntatore puo essere trasformato in un qualsiasi altro tipo di puntatore: (implicitamente o esplicitamente)

– da int* a double* , da void* a Persona*etc.

• Semantica: = “quello che fa”

– L’indirizzo rimane lo stesso, cambia l’interpretazione di ciò che ci trovo

– Nota: in effetti, a tempo di esecuzione, non avviene nulla!Cambiano solo cose nella testa del compilatore

• Costrutto estremamente POTENTE e di basso livello(e potenzialmente molto pacciugone)

Page 6: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Typecast fra puntatori: primo esempio

int* p;p = malloc( 4 );

int* p;p = (int*) malloc(4);

Esplicito (meglio, più chiaro):

Implicito:

Page 7: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione: e se la memoria finisce?

void* malloc(unsigned int n);

Se non c'è più memoria, l'allocazione "fallisce"

e malloc restituisce il valore speciale NULL• semanticamente, NULL è un "puntatore che non punta a nulla"• NULL è rappresentato dal valore 0

Quindi, il valore resituito dalle malloc va controllato !int* p;p = (int*) malloc(4);if (p == NULL) { /* finita memoria ... */}

oppure,più coincisamente

if (!p) {

Page 8: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione

Il costrutto sizeof è estremamente utile con le malloc.

Usare sempre, anche con i tipi base• int, short, float, double...

• remember: il C non prescrive quanti bytes occupano!

typedef struct { /*blah blah... un sacco di campi, array...*/} TipoStrano TipoStrano* p;p = (TipoStrano *) malloc(sizeof(TipoStrano));

Page 9: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Dellocazione

void free(void* p);

libera la memoria che era stata allocata all'indirizzo p.

Nota: p deve essere il risultato di una malloc!int* p;p = (int*) malloc(sizeof(int));... /* Qui uso (*p) */free(p);

se mi dimentico di deallocare, ho un cosiddetto memory leak

Remember: non c'è alcuna garbage collection in C !

Page 10: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione e Deallocazione: esempio

int proc() { int k; k=15;

... /* lavora con k */

return 0;};

int proc() { int* k; k = (int*)malloc( sizeof(int) ); *k = 15;

... /* lavora con *k */

free(k); return 0;};

k viene automaticamente allocato (i 4 bytes di memoria necessari al suo immagazzinamento vengono "prenotati").

k viene inizializzato (a 15)

all'uscita dalla procedura, i 4 bytes sono resi di nuovo disponibili

k viene esplicitamente allocato. (a tempo di esecuzione, si trovano i 4 bytes di memoria necessari al suo immagazzinamento. La locazione viene memorizzata in k).

k viene inizializzato (a 15)

all'uscita dalla procedura, dobbiamorendere i 4 bytes di nuovo disponibiliesplicitamente

usando l'allocazione dinamica:

usando l'allocazione automatica delle variabili locali:

Page 11: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Vi ricordate di quell'altro problemino...

• Cosa succede, se non si sa a priori* quanti elementi di un array ci serviranno**? – * quando scriviamo il programma– ** a tempo di esecuzione

• Necessità allocazione dinamica di array.

Page 12: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione di vettori

(void*) calloc(unsigned int n, unsigned int size);

calloc = contiguous allocation

Alloca n elementi contigui ciascuno grande size.

In pratica, alloca un area di memoria grande n x size

Per il resto, funziona come mallocint* p;p = (int*) calloc(100000,sizeof(int) );

Alloca un vettore di 100000 interi.

Esempio:

Page 13: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione di vettori

• Ricordiamoci sempre:

int* v = (int*) calloc(100000,sizeof(int) );

int v[100000];

A) fixed size vector:

B) vettore allocato dinamicamente:

• In entrambi i casi:• ho un vettore di 100000 interi• posso scrivere ad esempio:

v[2]= v[0] + 3 * v[1] ;

Page 14: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione di vettori

• Ricordiamoci sempre:

int* v = (int*) calloc(100000,sizeof(int) );

int v[100000];

A) fixed size vector:

B) vettore allocato dinamicamente:

• Differenza 1: dimensione variabile• se x è una var intera, posso scrivere:

• ma non posso scrivere:

int* v = (int*) calloc(x,sizeof(int) );

int v[x];

qua è richiesta una costante!

Page 15: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Allocazione di vettori

• Ricordiamoci sempre:

int* v = (int*) calloc(100000,sizeof(int) );

... /* usa v */

free(v);

int v[100000];

A) fixed size vector:

B) vettore allocato dinamicamente:

• Differenza 2: se ho allocato, devo deallocare

int* v = (int*) calloc(100000,sizeof(int) );

Page 16: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

• Differenza 3: fixed size = più efficiente• il solito prezzo da pagare per l'uso dei puntatori...• ...maggiorato• mettiamo che v valga 0xAA000000 :

se fixed:

se dinamco:

Allocazione di vettori

• Ricordiamoci sempre:

v[2]

int v[100000];

A) fixed size vector:

B) vettore allocato dinamicamente:

int* v = (int*) calloc(100000,sizeof(int) );

compilazione

compilazionev[2]READ TEMP0 0xAA000000ADD TEMP0 8READ TEMP TEMP0

READ TEMP 0xAA000008

0xAA000000 + 2 x sizeof(int)ma precalcolato staticamente

Page 17: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

• Differenza 4: • vengono allocati in zone diverse della

memoria...• come vedremo nella lezione sulla

gestione della memoria

Allocazione di vettori

• Ricordiamoci sempre:

int v[100000];

A) fixed size vector:

B) vettore allocato dinamicamente:

int* v = (int*) calloc(100000,sizeof(int) );

Page 18: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Puntatori: operazioni a basso livello

Esercizio:

• Sappiamo che un double occupa 8 bytes.• Dato un double, quale è il valore di questi

8 bytes?• Per esempio, quali 8 bytes compongono il

valore 3.14159256 ?

un numero in virgola mobilea doppia precisione

di solito, ma dipende dall'implementazione

Page 19: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Puntatori: operazioni a basso livello

spazio riservato per la variabile d (8 bytes)

int main(){

1B903C321B903C33

1B903C341B903C35

1B903C361B903C37

1B903C381B903C39

1B903C3A1B903C3B

1B903C3C

dobule d;

Page 20: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Puntatori: operazioni a basso livello

1B903C321B903C33

1B903C341B903C35

1B903C361B903C37

1B903C381B903C39

1B903C3A1B903C3B

1B903C3C

spazio riservato per la variabile d (8 bytes)

c o d i f i c a d i 3 . 1 4 1 5 9 2 5 6

int main(){ dobule d; d = 3.14159256; Byte * v ;

un puntatore a Byte che farà da vettore di Bytes

ma il tipo "Byte" non è definito! Definirlo, ad es fuori dalla proc "main" (vedere lez. 2)

Page 21: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

v = & d;

Puntatori: operazioni a basso livello

1B903C321B903C33

1B903C341B903C35

1B903C361B903C37

1B903C381B903C39

1B903C3A1B903C3B

1B903C3C

spazio riservato per la variabile d (8 bytes)

c o d i f i c a d i 3 . 1 4 1 5 9 2 5 6

int main(){ dobule d; d = 3.14159256; Byte * v ;

v[0]

v[1]

v[2]

v[3]

v[4]

v[5]

v[6]

v[7]

for (i=0; i<8; i++) printf("%d,",v[i]);

v = (Byte*) & d; for (i=0; i< sizeof(double); i++) printf("%d,",v[i]);

int i;

}

Page 22: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Puntatori: operazioni a basso livello

• A casa, provate questo programma, e scopriamo:– quali sono gli 8 bytes che compongono il double 3.14159256– quali sono gli 8 bytes che compongono il double 6.022 x 1023

• e, adattando il programma agli interi:– quali sono i 4 bytes che compongono l'int +1000000

– quali sono i 4 bytes che compongono l'int +1

– quali sono i 4 bytes che compongono l'int -1

• a seconda di quale architettura viene usata, potremmo trovare risposte diverse!– domanda: sarebbe potuto succedere in Java?

Page 23: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Puntatori

• Molto potenti...– vettori di dimensione determinata

dinamicamente– passaggio di parametri per riferimento

• in un linguaggio che prevede passaggio solo per copia

– possibilità di scrivere codici più efficienti– controllo diretto delle risorse, a basso livello– strutture dati flessibili

• per esempio:

typedef struct { char nome[20]; char cognome[20]; int eta; Persona* padre, madre;} Persona;

Page 24: Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.

M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i - 2 0 0 7 / 0 8 - U n i v e r s i t à d e l l ’ I n s u b r i a

Puntatori

• Molto potenti...

"Ad un grande potere corrisponde una grande responsabilità."

– lo zio di Spiderman