Newsgroup: it.comp.lang.c++
Titolo: Variabili automatiche nei cicli

che succede se faccio una cosa del genere
std::vector<mia_classe> MioVettore;
for (int i = 0; i < 10; i++) {
	mia_classe MioOggetto(i);
	MioVettore.push_back(MioOggetto);
}
cosa succede riguardo alla allocazione delle istanze di mia_classe? ad
ogni ciclo viene generato una nuova istanza? e quando viene liberata
la memoria, alla fine di ogni ciclo oppure all'uscita del ciclo?
-- 
]\/[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

 la memoria, alla fine di ogni ciclo oppure all'uscita del ciclo?
E' lecito. Nel vettore non viene copiato il puntatore al tuo oggetto creato
dentro il ciclo (forse era questa la tua preoccupazione), che alla fine
viene distrutto, ma push_back() invoca il costruttore di copia (alla quale
tu dovrai fare attenzione, però, nel caso la classe contegga oggetti per la
quale una bit-copy creata automaticamente dal tuo compilatore non basta) e
crea una nuova istanza, duplicata, del tuo oggetto.
ciao.



la mia preoccupazione, invece, era sapere che fine fanno tutti quegli
oggetti creati con l'allocazione automatica... vengono deallocati? ne
viene allocato uno ogni volta (cioè mi conviene crearne uno fuori dal
ciclo e modificarlo nel ciclo, oppure mi conviene crearlo sempre
all'interno)? quando vengono deallocati (se faccio un ciclo da 10000,
vengono creati 10000 oggetti e poi deallocati tutti insieme?)?


 la memoria, alla fine di ogni ciclo oppure all'uscita del ciclo?
Non ha molto senso parlare di 'allocazione' di memoria quando si tratta di 
variabili automatiche. Dal punto di vista del programmatore, intendo.
Cosa ti stai chiedendo esattamente? Quanto si estende il life-time degli 
oggetti instanziati? Ebbene, a ogni ciclo un oggetto viene creato e 
distrutto.
Però tu parlavi di memoria. Forse ti chiedi se ad ogni ciclo il programma 
abbia bisogno di un nuovo diverso frammento di memoria in cui costruire 
l'oggetto? No. Nulla di ciò che viene instanziato automaticamente 
sovravvive al ciclo successivo. Perciò la memoria viene riutilizzata.
Ad ogni modo, parlare di memoria quando si tratta di oggetti automatici 
(variabili o temporanei) significa di fatto parlare di 'stack' e di 'stack 
unwinding', che sono questioni che riguardano più chi scrive un 
compilatore che chi lo utilizza.
Non mi spiego, comunque, perché nel tuo esempio compaia un vector.
Max

 basta ...
Attenzione: il costruttore copia sintetizzato dal compilatore non effettua 
una copia bit-a-bit dell'oggetto. Non necessariamente, almeno. Effettua, 
invece, una copia detta 'member-wise': per ogni membro viene invocato il 
relativo costruttore copia. In generale, se l'oggetto incorpora altri 
oggetti dotati a loro volta di costruttore copia, il costruttore copia 
sintetizzato da compilatore è sufficiente.
Max

Non mi spiego, comunque, perché nel tuo esempio compaia un vector.
perché era il caso che mi era capitato e che mi aveva fatto venire in
mente la domanda... quindi piuttosto che scrivere un altro esempio, ho
copiato (più o meno) quello che avevo io e l'ho posto come esempio
nella domanda


 Max
Ciao. Interessante. Ammetto che non lo sapevo, io per copiare una classe che
conteneva tipi standard e std::string, creavo un costruttore di copia
apposito della mia classe che provvedesse a invocare il costruttore copia.
Allora avrei potuto evitare di scrivere codice... Appena posso ci provo!
Grazie, non si finisce mai d'imparare!
F.P.

 distruggere e farlo ricreare)
Dipende da quello che fanno costruttore e distruttore, rispetto a
quello che farebbe la tua funzione di modifica. Di per se
l'allocazione di memoria sullo stack ha un costo assolutamente
trascurabile.
Ciao,
Nicola

 la memoria, alla fine di ogni ciclo oppure all'uscita del ciclo?
Ad ogni ciclo viene costruita la tua classe, ne viene fatta una copia 
per essere ficcata nel vector e poi viene distrutta.
Questo in teoria. In pratica dipende dall'implementazione di vector.
stl::vector ti garantisce che tutte gli oggetti che contiene stanno
in memoria ad allocazioni contigue, di solito std::vector e' 
implementata per raddoppiare capacita' quando viene riempita.
Questo vuol dire che nel tuo caso accade:
costruzione di 1
copia di 1
distruzione di 1
		<--- Qui la capacita' e' 1
costruzione di 2
copia di 1        <- Non c'e' spazio e viene ricopiato il vettore
copia di 2        <- Costruzione variabile automatica
distruzione di 1  <- Qui viene distrutto il vecchio vettore
distruzione di 2  <- Distruzione della variabile automatica
                 <--- Qui la capacita' e' 2
costruzione di 3
copia di 1        <- Copia del vettore ( contiene 1 e 2 )
copia di 2
copia di 3        <- costruzione variabile automatica
distruzione di 1  <- Distruzione vecchio vettore
distruzione di 2
distruzione di 3
                 <--- Qui la capacita' e' 4
costruzione di 4
copia di 4        <- costruzione variabile automatica
distruzione di 4
                 <--- Qui la capacita' e' ancora 4
costruzione di 5
copia di 1	  <- Copia del vecchio vettore con 4 elementi
copia di 2
copia di 3
copia di 4
copia di 5        <- costruzione variabile automatica
distruzione di 1  <- distruzione vecchio vettore
distruzione di 2
distruzione di 3
distruzione di 4
distruzione di 5
                   <- Qui la capacita' e' 8
e cosi' via.
Per questi motivi prima di riempire un vettore
bisogna anche fare una stima di quanta roba ci si infila
e settare la capacita' iniziale adeguatamente.
G.

 la memoria, alla fine di ogni ciclo oppure all'uscita del ciclo?
Ad ogni ciclo viene costruita la tua classe, ne viene fatta una copia 
