Newsgroup: it.comp.lang.c++
Titolo: Memory leaks

Ho creato una classe polinomio:
class polinomio {
public:
 std::vector<double> p;
...
}
La memoria non viene allocata direttamente ma viene gestita attraverso il
vettore p che memorizza i coefficienti del polinomio.
Ho implementato anche varie operazioni matematiche tra cui per esempio il
prodotto per un double:
polinomio & polinomio::operator*(const double alfa){
 polinomio *ris=new polinomio;
 ris->p = p;
 *ris *= alfa;
 //std::cerr<<"\nPolinomio risultato"<<*ris;
 return *ris;
}
Per il calcolo effettivo viene utilizzato operator*=(double): mi rendo conto
che non è una soluzione particolarmente efficiente ma spero non sia questo a
causare il memory leak che ottengo quando faccio:
polinomio a(1,0)  //a=x
polinomio b(1,1,0) //b=x^2+x
a=(b+1)*2;
A quanto ne ho capito ottengo il memory leak perchè alloco memoria con new
quando richiamo operator+(double) e operator*(double), che poi non mi
preoccupo di liberare con delete. Ma dove posso mettere delete?
Potrei evitare l'inconveniente restituendo i risultati di ogni operazione
per valore invece che per riferimento ma non mi sembra una soluzione
accettabile specie se il mio polinomio è di dimensioni sufficientemente
elevata.
nota che l'operatore di assegnazione è semplicemente:
void polinomio::operator=(const polinomio & p1){
 p=p1.p;
}
Grazie e ciao ciao
Antonio

 }
Devi restituire per valore non per riferimento:
polinomio polinomio::operator*(const double alfa){
 polinomio ris;
 ris.p = p;
 ris *= alfa;
 //std::cerr<<"\nPolinomio risultato"<<*ris;
 return ris;
}
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 Devi restituire per valore non per riferimento:
Come ho già chiesto non c'è un'altra soluzione? Penso che sarebbe piuttosto
pesante il passaggio per valore specie se il polinomio è molto grosso.
Bye e grazie
Antonio

 > Devi restituire per valore non per riferimento:
Mi sono guardato un po' in giro su Internet e guardando un po' di header di
varie classi che implementano arrays (quindi memoria dinamica) e che fanno
uso di operatori in effetti è come dici tu: tutti gli operatori del tipo
+,-,*,... restituiscono per valore.
Nel codice che mi hai scritto:
polinomio polinomio::operator*(const double alfa){
 polinomio ris;
 ris.p = p;
 ris *= alfa;
 //std::cerr<<"\nPolinomio risultato"<<*ris;
 return ris;
}
ris viene effettivamente copiato quindi? è questo il prezzo da pagare per
poter usare gli operatori?
Bye
Antonio

 poter usare gli operatori?
Non tutti gli operatori. Ad esempio, i compound non hanno questo
problema dato che assegnano direttamente all'istanza corrente.


 pesante il passaggio per valore specie se il polinomio è molto grosso.
Puoi implementare 'polinomio' in modo che instanze distinte siano in
grado di condividire i dati fin quando questi non debbano essere
modificati (copy-on-write). In tal modo, puoi ridurre l'operazione di
copia dell'oggetto alla copia di un puntatore e l'incremento di un
contatore (reference-counting). Si tratta di una tecnica spesso
impiegata per implementare classi stringa. I vantaggi e i rischi di
questa soluzione (a proposito, in particolare, dell'implementazione di
std::string) sono stati più volte oggetto di discussione in questo
stesso gruppo e in comp.lang.c++.
Max

 problema dato che assegnano direttamente all'istanza corrente.
Toglimi una curiosità:
in quali situazioni è conveniente restituire una variabile per riferimento?
Ciao
Antonio