16
Allocazione dinamica di memoria in C++ Corso di programmazione I AA 2019/20 Corso di Laurea Triennale in Informatica Prof. Giovanni Maria Farinella Web: http://www.dmi.unict.it/farinella Email: [email protected] Dipartimento di Matematica e Informatica

Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include 2 double arr = (double )malloc( sizeof (double ) 10); 3

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Allocazione dinamica di memoria in C++

Corso di programmazione I AA 2019/20

Corso di Laurea Triennale in Informatica

Prof. Giovanni Maria Farinella

Web: http://www.dmi.unict.it/farinella

Email: [email protected]

Dipartimento di Matematica e Informatica

Page 2: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Allocazione dinamica: Heap o Free Store

Lo heap e un altro segmento di memoria adibito ai dati che

vengono allocati dinamicamente.

...

...Record di

attivazione per lafunzione main()(variabili locali,

parametri attuali)

Record diattivazione per la

funzione foo()(variabili locali,

parametri attuali,indirizzo di ritorno)

Segmento STACK

ab...

xreturn addr.

cd

...

...

Variabili allocate

dinamicamente

HEAP

...

Allocazione automatica Allocazione dinamica

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 1

Page 3: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Allocazione: operatore new del C++

1 i n t ∗a = new i n t ;

2 f l o a t ∗ f = new f l o a t ( 0 . 9 ) ;

3 ∗a = 1 0 ;

4 double ∗ a r r = new double [ 1 0 ] ;

L’operatore new permette di operare allocazione dinamica.

Il segmento di memoria per allocazione dinamica e denominato

Heap o free store.

Per istanziare un oggetto, per ospitare un array o una singola

variabile di un determinato tipo.

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 2

Page 4: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Deallocazione: operatore delete

A differenza della allocazione automatica (stack), la memoria

allocata dinamicamente va successivamente liberata

mediante l’operatore delete

1 i n t ∗a = new i n t ;

2 // . . .

3 d e l e t e a ; // d e a l l o c a z i o n e

deallocazione di un blocco di memoria

1 double ∗ a r r = new double [ 1 0 ] ;

2 // . .

3 d e l e t e [ ] a r r ;

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 3

Page 5: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Deallocazione: operatore delete

Il valore del puntatore (indirizzo di memoria) rimane invariato!

Si provi:

1 i n t ∗a = new i n t ;

2 double ∗ a r r = new double [ 1 0 ] ;

3 cout << a r r << end l ; // 0 xaabb1244

4 // . . .

5 d e l e t e a ; // d e a l l o c a z i o n e

6 // . .

7 d e l e t e [ ] a r r ;

8 cout << a r r << end l ; //0 xaabb1244

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 4

Page 6: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Memory leak

1 double ∗ a r r = new double [ 1 0 ] ;

2 // . .

3 double ∗v = new double [ 1 5 ] ;

4 // . .

5 v = a r r ;

A seguito della copia di un differente indirizzo di memoria nella variabile

v (“effetto aliasing”), si perde il riferimento (indirizzo) al blocco di

memoria di 15 elementi double.

Deallocare il blocco di memoria con l’operatore delete ? Non piu

possibile!

Puo essere un problema, ad esempio un Web server (centinaia di gg di

uptime!)

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 5

Page 7: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Double Deletion

1 double ∗ a r r = new double [ 1 0 ] ;

2 // . .

3 d e l e t e [ ] a r r ;

4 // . .

5 d e l e t e [ ] a r r ;

Puo capitare, soprattutto in un programma lungo e complesso di operare,

per errore, una doppia delete.

Cosa succede alla riga 5? Come gia detto in precedenza, il valore del

puntatore, dopo la delete, rimane invariato.

Il tentativo di deallocazione avra un comportamento indefinito, ovvero

non predicibile e possibilmente disastroso.

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 6

Page 8: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Double Deletion

1 double ∗ a r r = new double [ 1 0 ] ;

2 // . .

3 i f ( a r r ){4 d e l e t e [ ] a r r ;

5 a r r = n u l l p t r ;

6 }7 // . . a l t r i t e n t a t i v i d i d e a l l o c a z i o n e

Buona norma, ad ogni tentativo di deallocazione

• inserire un controllo sul valore del puntatore

• “azzerare” il puntatore dopo la delete

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 7

Page 9: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Premature deletion

1 double ∗ a r r = new double [ 1 0 ] ;

2 // . .

3 double ∗v = a r r ;

4 // . .

5 i f ( a r r ){6 d e l e t e [ ] a r r ;

7 a r r = n u l l p t r ;

8 }9 // . .

10 v [ 5 ] = 4 . 56789 ; // ! ! !

Dopo la delete di arr, operata per errore, esso sara nullptr, ma v

conserva il vecchio valore di arr!!

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 8

Page 10: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Funzioni che restituiscono un puntatore

1 i n t ∗ f unc ( i n t k ){2 i n t a r r [ k ] ;

3 f o r ( i n t i =0; i<k ; i++)

4 a r r [ k ] = 2∗k ;5 r e t u r n a r r ;

6 }7

8 i n t ∗ a r r a y = func ( 1 0 ) ;

Corretto? .. NO!

Infatti arr allocato automaticamente nello stack. Dobbiamo

ricordare cosa accade dopo l’istruzione return al record di

attivazione dello stack della funzione..

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 9

Page 11: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Funzioni che restituiscono un puntatore

1 i n t ∗ f unc ( i n t k ){2 i n t ∗ a r r = new i n t [ k ] ;

3 f o r ( i n t i =0; i<k ; i++)

4 a r r [ k ] = 2∗k ;5 r e t u r n a r r ;

6 }7

8 i n t ∗ a r r a y = func ( 1 0 ) ;

Corretto? .. SI!

arr allocato dinamicamente nel free store.

Memoria allocata per arr nel free store non sara liberata fino a

chiamata delete [].

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 10

Page 12: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Allocazione dinamica in C: malloc() e free()

1 #i n c l u d e <c s t d l i b >

2 double ∗ a r r = ( double ∗) malloc( s i z e o f ( double ) ∗ 10 ) ;

3 // . .

4 free(arr) ; // d e a l l o c a z i o n e

malloc() alloca dinamicamente un blocco di memoria:

• argomento e dimensione in byte (importante l’uso di sizeof:

portabilita!)

• restituisce un puntatore generico, ovvero di tipo void *, per

questo bisogna operare un type casting al tipo desiderato.

La funzione free() libera la memoria precedentemente allocata,

come delete in C++.

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 11

Page 13: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Allocazione dinamica di un array multidimensionale

1 #d e f i n e COLS 10

2 #d e f i n e ROWS 5

3 double ∗ a r r [ROWS] ;

4 // oppure

5 double ∗∗ a r r = new double ∗ [ROWS] ;

6 f o r ( i n t i =0; i<ROWS; i ++)

7 a r r [ i ]=new double [ COLS ] ;

1. Allocazione automatica (nello stack, linea 3) o dinamica (free

store/heap, linea 5) di un vettore di (ROWS) puntatori a tipo double.

2. Allocazione dinamica di ROWS vettori di COLS celle di tipo

double.

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 12

Page 14: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Allocazione dinamica di un array multidimensionale

0xaabb11

0x...

a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] ... ... a[0][M]

int *a[N] 0x445566 0x44556a ...

a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] ... ... a[1][M]

...

N x M

Stack ofree store Free store

a[0]

a[1]

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 13

Page 15: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

Allocazione dinamica di un array multidimensionale

1 double ∗ a r r [ROWS] ;

2 // oppure

3 double ∗∗ a r r = new double ∗ [ROWS] ;

4 f o r ( i n t i =0; i<ROWS; i ++)

5 a r r [ i ]=new double [ COLS ] ;

Accesso agli elementi (NB linea 3)

1 a r r [ i ] [ j ] ;

2 (∗ ( a r r+i ) ) [ j ] ;

3 *(arr+i)[j] ; //NO: ==∗( a r r+i+j )==a r r [ i+j ] [ 0 ]

4 ∗( a r r [ i ] + j ) ;

5 ∗ (∗ ( a r r+i ) + j ) ;

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 14

Page 16: Allocazione dinamica di memoria in C++€¦ · Allocazione dinamica in C: malloc() e free() 1 #include  2 double arr = (double )malloc( sizeof (double ) 10); 3

FINE

Prof. Giovanni Maria Farinella DMI UNICT [PDF generato il 12 novembre 2020 alle ore 03:46] 15