{ File: puntator.pas } { Scopo: esempi base su puntatori con commenti dettagliati sulla gestione della memoria a run time } program ProvaPuntatori; type PuntatoreAIntero = ^integer; var pi, pj : PuntatoreAIntero; procedure CambiaIntero (p: PuntatoreAIntero); begin p^ := -222 end; { CambiaIntero } procedure AllocaIntero (var q: PuntatoreAIntero); begin new(q); q^ := -333 end; { AllocaIntero } begin { ProvaPuntatori } { SITUAZIONE INIZIALE **STACK** **HEAP** _________ | | | ? | | 001 |========| | ? | | 002 RDA di pi| ? | | ? | | 003 ProvaPuntatori pj| ? | | ... | | ... |________| |_______|_| #################### } new(pi); { allocazione dinamica di memoria } { _________ | | | ? | | 001 |========| | ? | | 002 RDA di pi| -------------->| ? |*| 003 ProvaPuntatori pj| ? | | ... | | ... |________| |_______|_| #################### } pi^ := 150; { ora pi^ ha un valore significativo } { _________ | | | ? | | 001 |========| | ? | | 002 RDA di pi| -------------->| 150 |*| 003 ProvaPuntatori pj| ? | | ... | | ... |________| |_______|_| #################### } pj := pi; { pi e pj PUNTANO ALLA STESSA CELLA DI MEMORIA } { _________ | | | ? | | 001 |========| | ? | | 002 RDA di pi| -------------->| 150 |*| 003 ProvaPuntatori | | | ... | | pj| --------->-- | ... | | ... |________| |_______|_| #################### } dispose(pj); { deallocazione di pj, E QUINDI ANCHE DI pi } { _________ | | | ? | | 001 |========| | ? | | 002 RDA di pi| -------------->| ? | | 003 ProvaPuntatori | | | ... | | pj| --------->-- | ... | | ... |________| |_______|_| #################### } new(pi); { allocazione dinamica di memoria } { _________ | | ---->| ? |*| 001 |========| | | ? | | 002 RDA di pi| ------->- ->| ? | | 003 ProvaPuntatori | | | | ... | | ... pj| ------->---- | ... | | ... |________| |_______|_| #################### } pi^ := 4000; { ora pi^ ha di nuovo un valore significativo } { _________ | | ---->| 4000 |*| 001 |========| | | ? | | 002 RDA di pi| ------->- ->| ? | | 003 ProvaPuntatori | | | | ... | | ... pj| ------->---- | ... | | ... |________| |_______|_| #################### } new(pj); { allocazione dinamica di memoria } { _________ | | ---->| 4000 |*| 001 |========| | | ? | | 002 RDA di pi| ------->- | ... | | ... ProvaPuntatori pj| -------------->| ? |*| 573 |________| | ... | | ... |_______|_| #################### } pj^ := pi^; { le celle contengono lo stesso valore } { _________ | | ---->| 4000 |*| 001 |========| | | ? | | 002 RDA di pi| --------- | ... | | ... ProvaPuntatori pj| -------------->| 4000 |*| 573 |________| | ... | | ... |_______|_| } new(pj); { ERRORE METODOLOGICO: HO PERSO UNA CELLA DI MEMORIA } { _________ | | ---->| 4000 |*| 001 |========| | | ? | | 002 RDA di pi| --------- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| #################### } CambiaIntero(pi); { PRIMA FASE: creazione del record di attivazione di CambiaIntero e copia del parametro attuale (pi) nel parametro formale (p). (Poiche` si tratta di puntatori, corrisponde a fare puntare il par. formale alla stessa locazione dove punta il par. attuale.) | | RDA di |========| _________ CambiaIntero p | -------->------>| 4000 |*| 001 |========| | | ? | | 002 RDA di pi| ------->- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| SECONDA FASE: esecuzione del codice della procedura CambiaIntero. | | RDA di |========| _________ CambiaIntero p | ------->------>| -222 |*| 001 |========| | | ? | | 002 RDA di pi| ------->- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| TERZA FASE: ritorno da CambiaIntero: NOTA: pi NON E' CAMBIATO, MA pi^ SI!!! _________ | | ---->| -222 |*| 001 |========| | | ? | | 002 RDA di pi| --------- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| #################### } dispose(pi); { _________ | | ---->| ? | | 001 |========| | | ? | | 002 RDA di pi| --------- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| #################### } AllocaIntero(pi); { PRIMA FASE: creazione del record di attivazione di AllocaIntero e collegamento tra par. attuale (pi) e parametro formale (q). | | RDA di |========| _________ AllocaIntero q | vedi pi| ---->| ? | | 001 |========| | | ? | | 002 RDA di pi| --------- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| SECONDA FASE: esecuzione del codice di AllocaIntero: istruzione new(q); ===> allocazione dinamica della memoria (Poiche` il parametro attuale pi e` stato passato per variabile, ogni variazione su q si riflette anche su pi.) | | _________ RDA di |========| | ? | | 001 AllocaIntero q | vedi pi| ---->| ? |*| 002 |========| | | ... | | ... RDA di pi| ------->- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| Esecuzione del codice di AllocaIntero: istruzione q^:= -333 | | _________ RDA di |========| | ? | | 001 AllocaIntero q | vedi pi| ---->| -333 |*| 002 |========| | | ... | | ... RDA di pi| ------->- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| TERZA FASE: ritorno da CambiaIntero: NOTA: SONO CAMBIATI SIA pi CHE pi^!!! _________ | ? | | 001 | | ---->| -333 |*| 002 |========| | | ? | | ... RDA di pi| --------- | ... | | ... ProvaPuntatori pj| ---------- | 4000 |*| 573 |________| | | ... | | ... --->| ? |*| 812 | ... | | ... |_______|_| #################### } end. { ProvaPuntatori }