Newsgroup: it.comp.lang.c++
Titolo: Null pointer assignment

Qualcuno sa spiegarmi dove sbaglio?:
class Vettore {
  private:
     int dim;
     float *ptr;
  public:
     Vettore(int);
     ~Vettore();
     Vettore operator+(Vettore &);
     float & operator[](int);
     void set();
};
Vettore::Vettore(int d) {
   if (d<=0) cout << "Dimensione errata";
   else
  dim=d;
  ptr=new float[dim];
}
Vettore::~Vettore() {
   delete [] ptr;
}
Vettore Vettore::operator+(Vettore & vett) {
   Vettore sum(dim);
   if (dim!=vett.dim) cout << "Impossibile" << endl;
   else {
 for (int i=0; i<dim; i++) {
  sum[i]+=vett[i];
 }
   }
   return(sum);
}
float & Vettore::operator[](int comp) {
   return ptr[comp];
}
void Vettore::set() {
   float *comp;
   comp=new float;
   for (int i=0; i<dim; i++) {
  cin >> *comp;
  ptr[i]=*comp;
   }
   delete comp;
}
void main() {
 Vettore a(2), b(2);
 a.set(); b.set();
 a+b;
 getch();
}
Il codice viene compilato senza problemi, ma se eseguo il programma alla
fine (dopo il getch()) compare la scritta "Null pointer assignment". Quale è
il motivo? Il primo che risponde riceverà in premio un frigorifero di
pelouche.
Cecco
Cecco

 pelouche.
Certo. Perche' il C++ implementa la semantica di copia di default ma nel tuo
caso la cosa non funziona. Prova, fatte salve le correzioni suddette, ad
aggiungere:
Vettore::Vettore(const Vettore&r)
    :dim(r.dim),ptr(new float[r.dim])
{
    for ( int i=0; i<dim; i++ )
        ptr[i]=r[i];
}
Vettore& operator=(const Vettore&r)
{
    if ( &r!=this ) {
        delete [] ptr;
        dim=r.dim;
        ptr=new float[dim];
        for ( int i=0; i<dim; i++ )
            ptr[i]=r[i];
    }
    return *this;
}
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 }
1) Quando ritorni il valore di sum, viene usato il costruttore di copia
per copiare la variabile locale sum nella variabile da ritornare:
non avendo ridefinito tale costruttore, il compilatore te ne fornisce
uno di default che si limita a copiare i valori dei campi, ma NON degli
oggetti puntati da questi campi: il campo ptr della variabile ritornata
quindi punta a sum.ptr, che viene deallocato dal distruttore.
Quando si usano campi puntatore, quindi, si devono sempre ridefinire
costruttore di copia e assegnazione, per evitare problemi come questo.
2) La somma non fa quello che ci si aspetta.
Ciao,
Alberto Griggio
P.S.: Per quanto riguarda il frigo di pelouche, puoi spedirmelo
tranquillamente per e-mail.


  
Meglio ancora e` sollevare un'eccezione, in fondo un vettore a dimensione
non strettamente positiva e` sicuramente un errore (serio) e forzare la
dimensione ad un qualsiasi valore e` arbitrario.
Paolo
--
Paolo Marotta
Home: 
http://web.tiscalinet.it/paolo_marotta
Master's Level in C++ Certified by Brainbench
http://www.brainbench.com/transcript.jsp?pid=2440649

 dimensione ad un qualsiasi valore e` arbitrario.
Si. Ma visto il codice che era stato postato ho evitato di aggiungere troppa
carne al fuoco. Cosi' come non ho corretto l'operator[] che ritorna una
reference e non fa nessuna verifica, l'operator + il cui parametro non era const
etc. etc.
