13. Strutture dati dinamiche Ing. Simona Colucci Informatica - CDL in Ingegneria Industriale- A.A
Indice Allocazione dinamica vs statica Allocazione e de-allocazione di memoria Liste e loro gestione Informatica - CDL in Ingegneria Industriale- A.A
Allocazione dinamica della memoria Gestione dinamica della memoria per memorizzare una quantità variabile di dati in funzione di esigenze note solo durante l’esecuzione del programma e modificabili durante l’esecuzione Consente di : –Aggiungere un nuovo elemento nell’area dati di un programma in fase di esecuzione –Eliminare l’elemento di memorizzazione in fase di cancellazione del dato stesso Necessita di un riferimento ai nuovi elementi di memorizzazione che non può avvenire mediante identificatori: –Uso di puntatori –Creazione di un nuovo elemento e restituzione di un riferimento al dato stesso Informatica - CDL in Ingegneria Industriale- A.A
Allocazione e cancellazione di memoria Allocazione : malloc (sizeof (TipoDato)); –Crea in memoria una variabile di tipo TipoDato, e restituisce come risultato l’indirizzo della variabile creata –Se P è una variabile di tipo puntatore a TipoDato, l’istruzione: P = malloc(sizeof(TipoDato)); assegna l’indirizzo restituito dalla funzione malloc a P Cancellazione : free(P) –Rilascia lo spazio di memoria puntato da P Le due funzioni sono in Informatica - CDL in Ingegneria Industriale- A.A
Gestione della memoria della macchina astratta Informatica - CDL in Ingegneria Industriale- A.A Record di attivazione di Proc Stack Heap 5 3 Punt1 Punt2... Stack: pila per la gestione delle variabili dichiarate (LIFO) Heap: “mucchio” per le variabili create dinamicamente (allocazione a deallocazione gestite direttamente dal programmatore)
Rischi della gestione dinamica della memoria Garbage production : –P = malloc(sizeof(TipoDato)); –P = Q; Dangling references: –P = Q; –free(Q); Informatica - CDL in Ingegneria Industriale- A.A
Costruzione e gestione della struttura dinamica(pseudotipo astratto) lista mediante puntatori: Lista e1e2en Ultimo elemento Lista dinamica Puntatore alla “testa di lista” “testa di lista”“coda di lista” Elemento 1 della listaPuntatore a elemento 2Puntatore NULL
Informatica - CDL in Ingegneria Industriale- A.A Invece di dichiarare il tipo lista, si dichiarano i suoi elementi : typedef struct{ int Info; ElemLista *Prox; }ElemLista; typedef ElemLista*ListaDiElem Alternative: ElemLista *Lista1; ListaDiElemLista1, Lista2, Lista3; Dichiarazione lista dinamica
Operazioni sulle liste: Inizializzazione (1) Informatica - CDL in Ingegneria Industriale- A.A Assegna il valore NULL alla variabile “testa della lista”: Effettua l’operazione: Inizializza (Lista) : Lista Se però vogliamo eseguire l’operazione in maniera parametrica: …
Informatica - CDL in Ingegneria Industriale- A.A #include voidInizializza (ListaDiElem *Lista) /* Lista è la variabile locale che punta alla "testa di lista". La funzione assegna alla “testa di lista" il valore NULL corrispondente al valore di lista vuota */ { *Lista = NULL; } Lista1 Lista Inizializzazione (2) L’istruzione Inizializza(&Lista1); produce: Al termine dell’esecuzione, il parametro formale Lista viene eliminato
Informatica - CDL in Ingegneria Industriale- A.A booleanListaVuota (ListaDiElem Lista) /* Produce il valore true se la lista passata come parametro è vuota, false in caso contrario, a Lista viene passato il valore contenuto nella variabile testa di lista. Lista punta pertanto al primo elemento della lista considerata */ { if (Lista == NULL) return true; else return false; } La chiamata sarà: ListaVuota (Lista1) Controllo di lista vuota
Informatica - CDL in Ingegneria Industriale- A.A boolean Ricerca (ListaDiElem Lista, int ElemCercato) { ElemLista*Cursore; if (Lista != NULL) { Cursore = Lista;/* La lista non è vuota */ while (Cursore != NULL) { if (Cursore–>Info == ElemCercato) return true; Cursore = Cursore–>Prox; /* In questa maniera Cursore viene fatto puntare all'elemento successivo della lista */ } return false; } Ricerca di un elemento nella lista
Informatica - CDL in Ingegneria Industriale- A.A boolean Ricerca (ListaDiElem Lista, int ElemCercato) { if (Lista == NULL) return false; else if (Lista–>Info == ElemCercato) return true; else return Ricerca(Lista–>Prox, ElemCercato); } Ricerca di un elemento nella lista, versione ricorsiva
Informatica - CDL in Ingegneria Industriale- A.A Inserimento di un nuovo elemento in testa alla lista (1) in testa alla lista (1) Punt = malloc(sizeof(ElemLista)); Punt–>Info = Elem; Lista e1e2en Punt Lista e1e2en Punt Elem
Informatica - CDL in Ingegneria Industriale- A.A Infine si collega il nuovo elemento al precedente primo elemento della lista e la testa della lista viene fatta puntare al nuovo elemento: Lista e1e2en Punt Elem Inserimento di un nuovo elemento in testa alla lista (2) in testa alla lista (2)
Informatica - CDL in Ingegneria Industriale- A.A voidInsercisciInTesta (ListaDiElem *Lista, int Elem) { ElemLista*Punt; /* Allocazione dello spazio necessario per la memorizzazione del nuovo elemento e inizializzazione del puntatore */ Punt = malloc(sizeof(ElemLista)); Punt–>Info = Elem; Punt–>Prox = *Lista; *Lista = Punt; } Lista1 e1e2en Lista Punt Elem Inserimento di un nuovo elemento in testa alla lista (3) in testa alla lista (3)
Informatica - CDL in Ingegneria Industriale- A.A voidInserisciInCoda (ListaDiElem *Lista, int Elem); { ElemLista*Punt; if (ListaVuota (*Lista)) { Punt = malloc(sizeof(ElemLista)); Punt–>Prox = NULL; Punt–>Info = Elem; *Lista = Punt; } else InserisciIncoda (&((*Lista)–>Prox), Elem); } Inserimento di un nuovo elemento in coda alla lista(1) in coda alla lista(1)
Informatica - CDL in Ingegneria Industriale- A.A e1e2en-1en Lista1 Lista*1Lista*2Lista*3Lista*nLista*n+1 e1e2en-1en Lista1 Lista*1Lista*2Lista*3 Lista*n+1 Punt Elem Inserimento di un nuovo elemento in coda alla lista(2) in coda alla lista(2)
Inserimento di un nuovo elemento in coda alla lista(3) Informatica - CDL in Ingegneria Industriale- A.A e1e2en-1en Lista1 Lista*1Lista*2Lista*3 Lista*n+1 Punt Elem e1e2en-1en Lista1 Lista*1Lista*2Lista*3 Lista*n+1 Punt Elem
Esercizi in aula Informatica - CDL in Ingegneria Industriale- A.A II Esonero FI1 IT Scrivere le istruzioni per l’allocazione dinamica di una variabile destinata a contenere un cognome. In quale area di memoria viene allocata tale variabile? Quali potrebbero essere gli inconvenienti di tale allocazione? Sia data una lista di numeri reali. Scrivere le istruzioni in linguaggio C per definire tale lista e allocarne un nuovo nodo.