Il 0% ha trovato utile questo documento (0 voti)
8 visualizzazioni16 pagine

19 Dynamic Memory Allocation

Caricato da

Manuel Novi
Copyright
© All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
8 visualizzazioni16 pagine

19 Dynamic Memory Allocation

Caricato da

Manuel Novi
Copyright
© All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd

Allocazione dinamica di memoria in C++

Corso di programmazione I (A-L) AA 2019/20


Corso di Laurea Triennale in Informatica

Fabrizio Messina
messina@[Link]

Dipartimento di Matematica e Informatica


Allocazione dinamica: Heap o Free Store

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


vengono allocati dinamicamente.
Segmento STACK HEAP

... Record di ...


attivazione per la
funzione foo()
(variabili locali, Variabili
d
c parametri attuali, allocate
x indirizzo di ritorno) dinamicamente
return addr.
... ...
Record di
attivazione per la
funzione main()
... (variabili locali, ...
b parametri attuali)
a

Allocazione automatica Allocazione dinamica

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 1
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 = 10;
4 double ∗ a r r = new double [ 1 0 ] ;

L’operatore new permette di operare allocazione dinamica.


Il segmento di memoria per allocazione dinamica è denominato
Heap o free store.
Per istanziare un oggetto, per ospitare un array o una singola
variabile di un determinato tipo.

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 2
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 doubl e ∗ a r r = new double [ 1 0 ] ;
2 // . .
3 delete [ ] arr ;

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 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 doubl e ∗ a r r = new double [ 1 0 ] ;
3 c o u t << a r r << e n d 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 delete [ ] arr ;
8 c o u t << a r r << e n d l ; // 0 xaabb1244

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 4
Memory leak

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


2 // . .
3 doubl e ∗ v = new double [ 1 5 ] ;
4 // . .
5 v = arr ;

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 più
possibile!
Può essere un problema, ad esempio un Web server (centinaia di gg di
uptime!)

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 5
Double Deletion

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


2 // . .
3 delete [ ] arr ;
4 // . .
5 delete [ ] arr ;

Può capitare, soprattutto in un programma lungo e complesso di operare,


per errore, una doppia delete.
Cosa succede alla riga 5? Come già detto in precedenza, il valore del
puntatore, dopo la delete, rimane invariato.
Il tentativo di deallocazione avrà un comportamento indefinito, ovvero
non predicibile e possibilmente disastroso.

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 6
Double Deletion

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


2 // . .
3 i f ( a r r ){
4 delete [ ] arr ;
5 arr = nullptr ;
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

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 7
Premature deletion

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


2 // . .
3 doubl e ∗ v = a r r ;
4 // . .
5 i f ( a r r ){
6 delete [ ] arr ;
7 arr = nullptr ;
8 }
9 // . .
10 v [ 5 ] = 4 . 5 6 7 8 9 ; // ! ! !

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


conserva il vecchio valore di arr!!

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 8
Funzioni che restituiscono un puntatore

1 i n t ∗ func ( i n t k ){
2 int arr [ k ] ;
3 f o r ( i n t i =0; i <k ; i ++)
4 a r r [ k ] = 2∗ k ;
5 return arr ;
6 }
7
8 int ∗ array = func (10);

Corretto? .. NO!
Infatti arr allocato automaticamente nello stack. Dobbiamo
ricordare cosa accade dopo l’istruzione return al record di
attivazione dello stack della funzione..

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 9
Funzioni che restituiscono un puntatore

1 i n t ∗ func ( 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 return arr ;
6 }
7
8 int ∗ array = func (10);

Corretto? .. SI!
arr allocato dinamicamente nel free store.
Memoria allocata per arr nel free store non sarà liberata fino a
chiamata delete [].

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 10
Allocazione dinamica in C: malloc() e free()

1 #i n c l u d e < c s t d l i b >
2 doubl e ∗ a r r = ( double ∗ ) malloc ( s i z e o f ( double ) ∗ 1 0 ) ;
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 è dimensione in byte (importante l’uso di sizeof:


portabilità!)
• 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++.

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 11
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 // o p p u r e
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.

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 12
Allocazione dinamica di un array multidimensionale

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

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

NxM

Stack o
Free store
free store

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 13
Allocazione dinamica di un array multidimensionale

1 double ∗ a r r [ROWS ] ;
2 // o p p u r e
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 arr [ 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 ) ;

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 14
Esempi svolti

Esempi
19 [Link]
19 [Link]
19 [Link]
19 [Link]
19 [Link]
19 [Link]

Fabrizio Messina DMI Unict [PDF generato il 5 novembre 2019 alle ore 09:38] 15

Potrebbero piacerti anche