[Corsopoc] dubbio amletico su new

Andrea Leofreddi andrea@lugroma2.org
09 Jan 2003 03:42:23 +0100


On Wed, 2003-01-08 at 21:53, Riccardo Moja wrote: 
> 
> salve a tutti, è già da un anno (da quando ho fatto fondamenti 1) che un dubbio corrode la mia povera mente, un dubbio così incredibile quanto (almeno penso) stupido.
> allora, in c++ ci sono new e delete, in java solo new e va bene. new mi serve per gestire la memoria dinamicamente, ma sinceramente io non ne ho ancora capito l'utilità.
> 
> cioè supponiamo che io dobba creare una applicazione per una banca, la quale deve solo registrare il cognome di una persona e quanti soldi ha la persona,
> faccio una classe persona con un array nome[xx] e un int per tenere il conto dei soldi e poi tutti i metodi che servono per gestire queste variabili, (per aggiungere i soldi, prelevarli, mostrare il conto ecc ecc).
> 
> Però io voglio che questa applicazione funzioni in questo modo:
> all'inizio nel "database" delle persone non c'è niente
> Poi una persona arriva alla banca e apre un conto, quindi nel database ci va una persona 
> poi ne arriva un'altra e nel database ci sono 2 persone
> e così via...
> per fare questo senza gestire dinamicamente la memoria io potrei fare un array di tipo persona
> persona elenco [1000];
> così però mi occupa subito la memoria per 1000 persone (dato ke gli oggetti sono stati effettivamente creati).
> ma se io volessi fare in modo che quando non ci sono persone la memoria usata fosse 0?
> e quando ci fossero 4 persone la memoria usata fosse 4?
> da quello ke ho capito new serve a questo, ma non ho capito in che modo si possa usare per ottenere un simile risultato.

come hai detto tu, new e delete servono per gestire l'allocazione
dinamica dello spazio, cioe' la richiesta di memoria in caso di
necessita'. Rispetto all'allocazione nello stack, la memoria dinamica
(aka heap) ha la grande possibilita' di essere allocata ad hoc: una zona
allocata dinamicamente puo' crescere a richiesta oppure venire distrutta
quando non viene utilizzata. 

In pratica: l'esempio che hai fatto sopra e' il caso classico in cui la
memoria dinamica avrebbe vantaggi massicci sull'array statico, in
particolare: 

(i) non butterebbe 1000 - n * sizeof(persona) bytes se n << 1000
(inutile tenere spazio per 1000 entries se ne usiamo 3) 

(ii) potrebbe contenere molte piu' entries di 1000 a richiesta 
(utilizzando l'array statico invece, il tetto massimo di 1000 non
avrebbe potuto essere superato) 

> Devo usare gli array?
> Devo farlo tramite qualche metodo particolare?

Per quanto riguarda i dubbi su COME utilizzarla, ricordiamoci le piu'
frequenti strutture dati: 

(i) un vettore (aka array) di oggetti, anche se allocato dinamicamente,
generalemente risulterebbe *estremamente inefficiente* (anche se potesse
crescere a dismisura, richiederebbe la copia dello stesso quando
riallocato per cambiamenti di dimensione). In alcuni casi, se i dati
sono piccini e la loro contiguita' in memoria ci serve, un vettore e'
una scelta comoda. Il metodo classico per allocare un vettore di oggetti
in C(++) e':

MyType *ptr = new MyType[n];

In c++ un vettore di oggetti e' facilmente realizzabile tramite il
template std::vector. (*)
In Java un vettore di riferimenti a oggetti e' facilmente realizzabile
tramite il container Vector.

(ii) (double) linked list 
ampiamente spiegata e rispiegata in foi2 (mi pare?), e' quella che ha un
oggetto con un puntatore next. Aggiungi elementi a costo 0, ti costa la
ricerca. L'implementazione in C e' noiosa e stra-spiegata altrove, e non
staro' qui a scriverne l'ennesima implimentazione.

In c++ una (double linked) list e' facilmente realizzabile tramite il
template std::list (*). 
In Java una lista di riferimenti a oggetti e' facilmente realizzabile
tramite il container List.

(iii) altre. a secondo di quello che devi fare, potresti decidere di
utilizzare altre strutture dati a seconda della situazione (grafi,
alberi). 

Da notare il fatto che in Java, i container (nome delle implementazione
native del linguaggio di queste strutture dati) perdono parte delle loro
magiche proprieta' per il fatto che operano su riferimenti e non sugli
oggetti stessi (come fanno invece le stl in c++), quindi un vettore di
oggetti in java sara' comunque un vettore di riferimenti a oggetti!

(*) Fortunatamente in C++ esiste una stupendea libraria che (ignorata
nei corsi di fondamenti) chiamata Standard Template Library. STL
implementa vettori, liste, iteratori e un sacco di altra roba. Ottima
documentazione su STL la puoi trovare sul sito di silicon graphics,
http://www.sgi.com -> fast find -> STL. 

> Oppure dovrei smetterla di drogarmi?
no! le sigarette allegre e le pastiglie di fantasia sono amiche dei
programmatori 

> mah...
> spero che qualche buon'anima mi illumini al riguardo
spero di essere stato chiaro 

Regards 

-- 
Andrea Leofreddi

email:                       andrea@lugroma2.org
homepage: http://lupo.campus.uniroma2.it/~andrea