13. Strutture dati dinamiche
Ing. Simona Colucci
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Indice
• Allocazione dinamica vs statica
• Allocazione e de-allocazione di memoria
• Liste e loro gestione
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
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. 2012-2013
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 <stdlib.h>
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Gestione della memoria
della macchina astratta
...
Punt1
Punt2
Record di
attivazione
di Proc
...
Stack
5
3
Heap
•Stack: pila per la gestione delle variabili dichiarate (LIFO)
•Heap: “mucchio” per le variabili create dinamicamente (allocazione a
deallocazione gestite direttamente dal programmatore)
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
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. 2012-2013
Lista dinamica
• Costruzione e gestione della struttura dinamica(pseudotipo
astratto) lista mediante puntatori:
Elemento
Puntatore
1 della
a elemento
lista
2
Puntatore NULL
Ultimo
elemento
Lista
e1
e2
Puntatore alla
“testa di lista”“testa di lista”
en
“coda di lista”
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Dichiarazione lista dinamica
Invece di dichiarare il tipo lista, si dichiarano i suoi elementi:
typedef struct{
int
ElemLista
}ElemLista;
typedef
Alternative:
ElemLista
ListaDiElem
ElemLista
Info;
*Prox;
*ListaDiElem
*Lista1;
Lista1, Lista2, Lista3;
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Operazioni sulle liste:
Inizializzazione (1)
•
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. 2012-2013
Inizializzazione (2)
#include <stdlib.h>
void Inizializza (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;
}
•
L’istruzione
Inizializza(&Lista1);
produce:
Lista
Lista1
•
Al termine dell’esecuzione, il parametro formale Lista viene eliminato
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Controllo di lista vuota
boolean
ListaVuota (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)
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Ricerca di un elemento nella lista
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;
}
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Ricerca di un elemento nella lista,
versione ricorsiva
boolean Ricerca (ListaDiElem Lista, int ElemCercato)
{
if (Lista == NULL)
return false;
else
if (Lista–>Info == ElemCercato)
return true;
else
return Ricerca(Lista–>Prox, ElemCercato);
}
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Inserimento di un nuovo elemento
in testa alla lista (1)
Punt
Lista
e1
e2
en
Punt = malloc(sizeof(ElemLista));
Punt–>Info = Elem;
Punt
Elem
Lista
e1
e2
en
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Inserimento di un nuovo elemento
in testa alla lista (2)
•
Infine si collega il nuovo elemento al precedente primo elemento
della lista e la testa della lista viene fatta puntare al nuovo
elemento:
Punt
Elem
Lista
e1
e2
en
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Inserimento di un nuovo elemento
in testa alla lista (3)
void InsercisciInTesta (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;
}
Lista
Punt
Elem
e1
e2
en
Lista1
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Inserimento di un nuovo elemento
in coda alla lista(1)
void
InserisciInCoda (ListaDiElem
*Lista, int
{
ElemLista
*Punt;
if (ListaVuota (*Lista))
{
Punt = malloc(sizeof(ElemLista));
Punt–>Prox = NULL;
Punt–>Info = Elem;
*Lista = Punt;
}
else InserisciIncoda (&((*Lista)–>Prox), Elem);
}
Elem);
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Inserimento di un nuovo elemento
in coda alla lista(2)
Lista*1
Lista*2
e1
Lista*3
e2
Lista*n
en-1
Lista*n+1
en
Lista1
Lista*1
Lista*2
e1
Lista*3
e2
Lista*n+1
en-1
Punt
Elem
en
Lista1
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Inserimento di un nuovo elemento
in coda alla lista(3)
Lista*1
Lista*2
e1
Lista*3
e2
Lista*n+1
en-1
Punt
Elem
en
Lista1
Lista*1
Lista*2
e1
Lista*3
e2
Lista*n+1 Punt
en-1
en
Lista1
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013
Elem
Esercizi in aula
• 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.
Informatica - CDL in Ingegneria Industriale- A.A. 2012-2013