1 / 32

Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA

Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a. 2003-2004 – 3° ciclo. Memoria dinamica. La memoria dinamica è la memoria gestita dinamicamente a run-time dal sistema operativo e dal programma ( stack ed heap )

Download Presentation

Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a. 2003-2004 – 3° ciclo

  2. Memoria dinamica La memoria dinamica è la memoria gestita dinamicamente a run-time dal sistema operativo e dal programma (stack ed heap) E’ possibile (per un programma) allocare aree di memoria dinamicamente durante l’esecuzione ed accedere ad esse mediante puntatori. Gli oggetti così ottenuti sono detti dinamici ed allocati nella memoria libera.

  3. Memoriastack L’area di memoria stack é quella in cui viene allocato un “pacchetto” di dati non appena l’esecuzione passa dal programma chiamante a una funzione. Questo “pacchetto” contiene: - l’indirizzo di rientro nel programma chiamante - la lista degli argomenti passati alla funzione - il valore di ritorno della funzione e viene “impilato” sopra il pacchetto precedente (quello del progr. chiamante) e poi automaticamente rimosso dalla memoria appena l’esecuzione della funzione é terminata.

  4. Memoriastack Nella memoria stack vengono sistemati anche i dati relativi a tutte le variabili automatiche (cioè locali e non statiche) create dalla funzione. Il loro “tempo di vita” é legato all’esecuzione della funzione proprio perché, quando la funzione termina, l’intera area stack allocata viene rimossa.

  5. Memoriaheap Esiste un’altra area di memoria che il programma può utilizzare. Questa area, detta heap, è soggetta a regole completamente diverse da quelle che governano l’area stack. L’area heapnon é allocata automaticamente, ma solo su esplicita richiesta del programma (allocazionedinamicadellamemoria) L’area allocata non é identificata da un nome, ma é accessibile solo tramite dereferenziazione di un puntatore

  6. Memoriaheap La sua visibilità é legata a quella della variabilepuntatore che contiene il suo indirizzo Il suo tempo di vita coincide con l’intera durata del programma, a meno che non venga esplicitamente deallocata; se il puntatore va out of scope, l’area non é più accessibile, ma continua a occupare memoria inutilmente. L’allocazione dinamica della memoria si realizza tramite l’operatore prefissonew. La deallocazione di tale memoria si realizza tramite l’operatore unariodelete.

  7. Operatorenew L’operatorenew permette di allocare memoria per uno o più oggetti nell’area heap e ne restituisce l’indirizzo newtipo[dimensione] tipo é il tipo dell’oggetto (o degli oggetti) da creare dimensione é il numero degli oggetti, che vengono sistemati nella memoria heap consecutivamente; se questo operando é omesso, viene costruito un solo oggetto In caso di errore (memoria libera/dinamica non disponibile) restituisce il valore NULL

  8. Esempi int*punt = new int; alloca un oggetto int nell’area heap e usa il suo indirizzo per inizializzare il puntatore punt; struct anagrafico { ....... }; anagrafico* p; p = new anagrafico [100]; definisce la struttura anagrafico e dichiara un puntatore a tale struttura, a cui assegna l’indirizzo del primo di cento oggetti di tipo anagrafico, allocati nell’area heap.

  9. Operatoredelete L’operatore unariodeletedealloca (libera) la memoria dell’area heap puntata dall’operando. int*punt = new int; allocazione delete punt; deallocazione L’operatore delete non cancella la variabile puntatore né altera il suo contenuto: l’unico effetto é di liberare la memoria puntata rendendola disponibile per eventuali ulteriori allocazioni.

  10. Operatoredelete • L’operatore delete può essere applicato solo ad un puntatore che indirizza un oggetto allocato mediante una new mantenendo la correttezza semantica dell’operazione. • Non esiste alcun controllo sull’uso congruente degli operatori new e delete, sono sotto la sola gestione del programmatore.

  11. Operatoredelete Se delete punta a un’area in cui sono stati allocati più oggetti, l’operatore va ulteriormente specificato con una coppia di parentesi quadre (senza la dimensione, che il C++ é in grado di riconoscere automaticamente). float*punt = new float [100]; ( alloca 100 oggetti float) delete[] punt; (libera tutta la memoria allocata)

  12. Operatore delete L’operatore delete costituisce l’unico mezzo per deallocare memoria heap, che, altrimenti, sopravvive fino alla fine del programma, anche quando non é più raggiungibile. int* punt = new int; ( alloca un intero nell’area heap) int a; ( definisce la variabile a intera) punt = &a; (assegna a punt l’indirizzo di a) L’oggetto intero dell’area heap non é più raggiungibile in quanto con l’ultima assegnazione si è distrutto il valore iniziale di p (indirizzo ritornato da new) !

  13. Puntatori • L’operatore di indirizzo & • Indirizzi, puntatori • Aritmetica dei puntatori • L’operatore di dereferenziazione *

  14. Operatore di indirizzo & L’operatore unario di indirizzo& restituisce l’indirizzo della locazione di memoria dell’operando Il valore restituito non va usato come l-value (in quanto l’indirizzo di memoria di una variabile non può essere assegnato in un’istruzione, ma è predeterminato)

  15. Operatore di indirizzo & Es.: &a ammesso &(a+1) non ammesso &a= bnon ammesso Perché? (in quanto l’indirizzo di memoria di una variabile non può essere modificato in un’istruzione, ma solo usato come riferimento in quanto è predeterminato e non modificabile)

  16. Indirizzo Valore Indirizzo Valore reg. 1000 “N” reg. 8000 reg. 1000 Variabile dato di tipo puntatore Variabile dato di tipo carattere Puntatori Una variabile di tipo puntatore é designata a contenere l’indirizzo di memoria di un’altra variabile (detta variabile puntata), la quale a sua volta può essere di qualunque tipo, anche non nativo (persino un altro puntatore!).

  17. Dichiarazione di variabile puntatore Esistono puntatori per ogni tipo di variabile puntata Un dato puntatore può puntare solo a un determinato tipo di variabili, quello specificato nella dichiarazione Si usa il qualificatore di tipo (suffisso) * Es. : int* pointer; dichiara la variabile pointer, puntatoread una qualunque variabile di tipoint Si può anche dichiarare un puntatore a puntatore. Es.: double** pointer_to_pointer;

  18. Puntatore void Un puntatore void è un puntatore generico che accetta come valore un indirizzo ma non punta ad un tipo dato ben determinato. Il puntatore void si riferisce ad oggetti di tipo diverso int i; int* pi=&i; char c; char* pc=&c; void* tp; tp=pi; *(int*) tp=3; tp=pc; *(char*) tp=‘c’;

  19. Assegnazione di valore a un puntatore NON si possono assegnare valori a un puntatore, salvo che in questi tre casi: • a un puntatore é assegnato il valore NULL (non punta a “niente”) • a un puntatore è assegnato l’indirizzo di una variabile esistente, restituito dall’operatore &( Es. int a; int* p; p=&a; ) • é eseguita un’operazione di allocazione dinamica della memoria

  20. Operazioni sui puntatori Operazioni fondamentali: Assegnazione di valore (indirizzo) ad un puntatore int* pi = &i p = q Riferimentoall’oggetto puntato *pi=3 Confronto tra puntatori (==, !=)

  21. Operazioni sui puntatori E’ possibile specificare che un dato puntatore non deve essere usato per modificare l’oggetto puntato attraverso la parola chiave const: int i; const int* p=&i; Le istruzioni in cui si usa p per aggiornare i vengono segnalate come erronee

  22. Operazioni sui puntatori E’ possibile specificare con la parola chiave const che un puntatore non deve essere modificato: int i; int* const p=&i; Le istruzioni in cui si vuole modificare il valore di p vengono segnalate come erronee

  23. Aritmetica dei puntatori (1) Il valore assunto da un puntatore é un numero intero che rappresenta, in byte, un indirizzo di memoria le operazioni di somma fra un puntatore e un valore intero (con risultato puntatore), oppure di sottrazione fra due puntatori (con risultato intero) vengono eseguite tenendo conto del tipo della variabile puntata Es.: se si incrementa un puntatore-a-float di 3 unità, il suo valore viene incrementato di 12 byte.

  24. Aritmetica dei puntatori (2) Se l’espressione p rappresenta l’indirizzo di un oggetto di tipo T, allora l’espressione p+1 rappresenta l’indirizzo di un oggetto di tipo T allocato consecutivamente in memoria. In generale: se i è un intero, se p rappresenta l’indirizzoaddrdi T che occupa n locazioni di memoria, allora l’espressionep+iha valoreaddr+ nxi

  25. Aritmetica dei puntatori (3) Le regole dell’aritmetica dei puntatori assicurano che il risultato sia sempre corretto, qualsiasi sia la lunghezza in byte della variabile puntata. Es.: se p punta a un elemento di un array, p++ punterà all’elemento successivo, qualunque sia il tipo (anche non nativo) dell’array

  26. L’operatore di dereferenziazione * L’operatore unario di dereferenziazione * di un puntatore restituisce il valore della variabile puntata dall’operando: come r-value, esegue un’operazione di estrazione Es.: a = *p;assegna ad a il valore della variabile puntata da p  come l-value, esegue un’operazione di inserimento Es.: *p = a; assegna il valore di a alla variabile puntata da p

  27. L’operatore di dereferenziazione * l’operazione di deref. é inversa a quella di indirizzo. Se assegniamo a un puntatore p l’indirizzo di una variabile a, p = &a; allora *p == a cioè la deref. di p coincide con a

  28. L’operatore di dereferenziazione * ATTENZIONE: non é detto il contrario !!! se si assegna alla deref. di p il valore di a, *p = a ; ciò non comporta automaticamente che in p si ritrovi l’indirizzo di a, ma semplicemente che il valore della variabile puntata da p coinciderà con a

  29. Puntatori e riferimenti Un riferimento è un nome alternativo per un oggetto e va sempre inizializzato Un riferimento è un puntatore costante che viene dereferenziato ogni volta che viene utilizzato void g() int ii=0; int& rr=ii; // inizializzazione rr++; // ii viene incrementato di 1 int *pp=&rr; // pp punta ad ii

  30. Attenzione! la dichiarazione di un puntatore comporta allocazione di memoria per la variabile puntatore, ma non per la variabile puntata. Es.: int* lista; alloca memoria per lista ma non per la variabile puntata da lista

  31. Esempio int a = 1; int b = 7; int* pa = &a; int* pb = &b; a 1 pa b 7 pb int temp; temp = a; a = b; b = temp; a 7 pa temp 1 Oppure, usando pa e pb b 1 pb int temp; temp = *pa; *pa = *pb; *pb = temp; Scambio dei valori di a e b

  32. Esempio int a = 1; int b = 7; int* pa = &a; int* pb = &b; a 1 pa b 7 pb int* tempp; tempp = pa; pa = pb; pb = tempp; a 1 pa tempp b 7 pb Scambio dei puntatori di a e b

More Related