Newsgroup: it.comp.lang.c++
Titolo: decisione tra allocazione statica e dinamica: riassunto

ho cercato di stilare un riassunto sui motivi per cui le istanze di
alcune classi in alcuni casi vanno allocate dinamicante o
staticamente, voglio vedere se siete d'accordo
allocare staticamente gli oggetti a meno che:
1) non si conoscano i parametri di inizializzazione durante la stesura
del codice, ma solo a run-time
2) l'oggetto in questione deve vivere anche dopo il termine della
funzione in cui viene creato
queste sono ovvie, ma forse ce ne sono altre
3) l'oggetto è molto grande
4) è espressamente detto nella documentazione che deve essere allocato
dinamicamente
per quanto riguarda la 4, e mi riferisco alla VCL, immagino che il
motivo possa essere quello che esista del codice nell'operator new
della classe, altrimenti non capisco il motivo
a questo punto, allora, un'altra domanda... perché avere codice
nell'operator new? cioè perché avere codice che funziona solo ad
allocazione dinamica e soprattutto perché impedire l'allocazione
statica (forse VCL ha altri motivi per questo, tipo il fatto che
deriva da Delphi?)
-- 
]\/[ad]\/[age (
www.mindreamz.net
)
"Un Maestro insegue semplicemente la sua visione di Eccellenza in
qualunque cosa sta facendo e lascia agli altri decidere se sta 
lavorando o giocando. A lui sembra sempre di fare entrambe." - Anonimo

 del codice, ma solo a run-time
?? Ma scusa,
obj* pippo=new obj(arg_noto_a_runtime);
non č uguale (ma molto meno efficiente) a
obj pippo(arg_noto_a_runtime);
No ?
-- 
LF

 deriva da Delphi?)
Vedi sopra.
Ciao,
Nicola

 tramite puntatore.
Ti chiedo una cortesia, puoi spiegarlo con un esempio? Sto seguendo il
thread e mi interessa molto, ma non ho compreso questo ultimo pezzo.

No ?
scusa... era una tara mentale che avevo da tempo, inconsciamente... in
realtà mi confondevo con un'altra cosa: allocare un vettore di oggetti
di cui non si conosce il numero, ad esempio una stringa
std::string lamiastringa;
cin >> lamiastringa;
char* vetchar = new char[lamiastringa.length()];


istanze delle classi sono sempre allocate dinamicamente.
perché questa scelta?


 perché questa scelta?
Perche' l'Object Pascal e' nato cosi' :-)
Ciao,
Nicola

effettuata esplicitamente chiamando new().
ok, dunque per oggetti grandi tu dici che è sconsigliabile
l'allocazione sullo stack (cioè miaclasse oggetto quando non è
globale, membri static, ecc.)...
dunque oggetti grandi => allocazione dinamica oppure statica, ma NON
automatica
altra domanda: c'è qualche controindicazione nel voler allocare tutto
dinamicamente, come fa java e vcl?


 dinamicamente, come fa java e vcl?
Almeno due mi vengono in mente immediatamente: peggioramento delle
prestazioni e non poter contare sull'esecuzione automatica del
distruttore all'uscita dallo scope di una variabile locale.
Ciao,
Nicola

 distruttore all'uscita dallo scope di una variabile locale.
Scusa, ma questi non sono problemi risolti dal Garbage collector?
CIAO!!!

 dico bene?
no, dici male :-).
Ricapitoliamo:
- allocazione automatica ("sullo stack"): parametri delle funzioni, valori
di ritorno, variabili locali.
- allocazione statica: variabili globali, variabili locali ma statiche
(dichiarate con static), membri di classe statici;
- allocazione dinamica: in genere e` quella "con new", ma nota che ci
possono anche essere delle eccezioni alla regola (ad esempio in alcune
occasioni quando sovraccarichi operator new o quando usi il placement new).
- head stile C: le classiche malloc/calloc/realloc; su particolari
implementazioni lo heep usato da malloc potrebbe essere lo stesso usato da
::operator new, ma a rigor di standard dobbiamo considerarlo un heap
diverso a tutti gli effetti.
ciao Anto
-- 
"Computer science is not about computers any more than astronomy
is about telescopes." -- EW Dijkstra

...

No, sono problemi *introdotti* dal garbage collector (che per altro
Delphi non ha). Se io scrivo
{
  MiaClasse a;
  .
  .
}
So che alla parentesi chiusa viene chiamato il distruttore di
MiaClasse. Se alloco dinamicamente la memoria in C++ ho
{
  MiaClasse * p = new MiaClasse;
  .
  .
  delete p;
}
e devo ricordarmi io di chiamare delete sia per liberare la memoria
sia per far chiamare il distruttore. Con un garbage collector come
quello di Java non solo non ho la certezza di quando viene chiamato il
distruttore (o meglio finalizzatore), ma non sono nemmeno sicuro che
venga chiamato.
Ciao,
Nicola

venga chiamato.
no? e a che serve il garbage collector se non a finalizzare gli
oggetti non piů utilizzati?


 oggetti non piů utilizzati?
No, il garbage collector serve a recuperare memoria quando ce n'e'
bisogno. Se non ce n'e' bisogno non la recupera e i finalizzatori non
vengono eseguiti.
Ciao,
Nicola

vengono eseguiti.
quando ce n'è bisogno?!? questa non l'ho capita... spieghi per favore?


 quando ce n'è bisogno?!? questa non l'ho capita... spieghi per favore?
Concettualmente lo scopo di un garbage collector e' dare l'illusione
di operare con memoria infinita: alloco finche' voglio e non mi
preoccupo di deallocare. Questo approccio fa a pugni con l'idea di
associare delle operazioni (distruttori, finalizzatori, ecc.) con il
termine del ciclo di vita di un oggetto.
In pratica i garbage collector cercano di mantenere libera una certa
percentuale della memoria che gestiscono; quando la memoria libera
scende sotto una determinata soglia, cercano di recuperare spazio tra
gli oggetti non piu' utilizzati (questo e' il momento in cui vengono
eseguiti i finalizzatori); se questo non riesce chiedono altra memoria
al sistema operativo.
Se la memoria e' sempre sufficiente, l'attivita' di recupero non viene
effettuata ed i finalizzatori non vengono chiamati.
Ciao,
Nicola

io ricordavo un approccio diverso... un garbage collector mantiene per
ogni oggetto un valore che indica tutti i riferimenti a
quell'oggetto... quando nessun altro oggetto si riferisce ad un certo
oggetto, questo viene distrutto
del resto non capisco perché sprecare tanta memoria... comunque "si
sa" quando un oggetto non serve piů... tanto vale distruggerlo subito,
perché aspettare?


 perché aspettare?
Del resto non capisco, perche' sprecare tempo a recuperare quando c'e'
la memoria? :-)
Ciao,
Nicola