Errore C2679 su allocazione di struttura

di il
37 risposte

Errore C2679 su allocazione di struttura

Salve a tutti
il file di include è il seguente:

 struct attributo
                {
                  int attribbuto;
                  char *valore;
                };
la funzione l'ho definita così:
int Bianca(struct attributo &numero,int &inbyte)
in fase di compilazione mi da
1>g:\classe numerica\test\bianca.cpp(37): error C2679: '=' binario: non è stato trovato alcun operatore che accetti un operando destro di tipo 'attributo *'. È anche possibile che non vi siano conversioni accettabili.
1> g:\classe numerica\test\include\rosalindac.sam(5): potrebbe essere 'attributo &attributo::operator =(const attributo &)'
    attributo *numerox=0;
              try { numerox = new attributo;
                    numero = numerox; } // qui mi da' l'errore!
              catch ( bad_alloc &err)
                   { numero=NULL; errore=105; }
              try { numero.valore= new char[inbyte]; }  // qui mi da' l'errore!
              catch (bad_alloc &err)
                   { numero.valore=NULL; delete numerox; errore=105; }
                    
gentilmente mi potreste dire come correggere l'errore.

37 Risposte

  • Re: Errore C2679 su allocazione di struttura

    
    int Bianca(struct attributo *numero,int &inbyte)
    
    Se passi un reference, passi un oggetto fatto e finito non un puntatore e il compilatore si lamenta.
    Se vuoi passare un reference allora:
    
                  try { numero.valore= new char[inbyte]; }  // qui mi da' l'errore!
                  catch (bad_alloc &err)
                       { numero.valore=NULL; errore=105; }
    
  • Re: Errore C2679 su allocazione di struttura

    Ciao shodan
    si lamenta lo stesso!
        attributo *numerox=0;
                  try { numerox = new attributo;
                        numero = numerox; } // qui mi da' l'errore! (linea 36)
                  catch ( bad_alloc &err)
                       { numero=NULL; errore=105; }
                       
    1>g:\classe numerica\test\bianca.cpp(36): error C2679: '=' binario: non è stato trovato alcun operatore che accetti un operando destro di tipo 'attributo *'. È anche possibile che non vi siano conversioni accettabili.
    1> g:\classe numerica\test\include\rosalindac.sam(5): potrebbe essere 'attributo &attributo::operator =(const attributo &)'
    1> durante la ricerca di corrispondenza con l'elenco di argomenti '(attributo, attributo *)'
  • Re: Errore C2679 su allocazione di struttura

    Ma che stai passando? Un reference o un puntatore?
  • Re: Errore C2679 su allocazione di struttura

    Devo passare il puntatore della variabile e del vettore che alloco.
    ed infatti l'errore me lo da quando vado a conservare i dati che ho allocato.
  • Re: Errore C2679 su allocazione di struttura

    Allora il prototipo dev'essere:
    
    int Bianca(struct attributo *numero,int &inbyte)
    
    non
    
    int Bianca(struct attributo &numero,int &inbyte)
    
    Tra l'altro se il corpo della funzione è questo:
    
        attributo *numerox=0;
                  try { numerox = new attributo;
                        numero = numerox; } // qui mi da' l'errore!
                  catch ( bad_alloc &err)
                       { numero=NULL; errore=105; }
                  try { numero.valore= new char[inbyte]; }  // qui mi da' l'errore!
                  catch (bad_alloc &err)
                       { numero.valore=NULL; delete numerox; errore=105; }
    
    ha comunque un altro errore (che si individua solo quando capita. Praticamente mai). Se ci rifletti su, vedrai che l'uso delle eccezioni fatto in quel modo è sbagliato.
  • Re: Errore C2679 su allocazione di struttura

    
                  try { attributo *numerox = new attributo;
                         numero = numerox; }
                  catch ( bad_alloc &err)
                       { numero.attribbuto = NULL; errore=105; }
                  try { numero.valore= new char[inbyte]; }
                  catch (bad_alloc &err)
                       { numero.valore=NULL; 
                       delete numero; //da errore
                       errore=105; }
                  modalita=0;
                  errore=Modifica_Attribbuto(numero,modalita,sattrib,dime);
                  if (errore !=0)
                    {
                      for (indy=0;indy<inbyte;indy++) 
                           { delete numero.valore; //da errore }
                      delete numero; // da errore
                      return errore;
                    }
    Adesso mi da l'errore nelle delete
    error C2440: 'delete': impossibile convertire da 'attributo' a 'void *'
    scusami che differenza c'è fra se facci i prototipo
    int Bianca(struct attributo *numero,int &inbyte)
    oppure
    int Bianca(struct attributo &numero,int &inbyte)
    e quando copio il puntatore allocato faccio:
    numero=*numerox;
    lo stesso non va in errore lo scoperto per sbaglio poco fa!
    pero credo ci sia una differenza tra i due modi.
  • Re: Errore C2679 su allocazione di struttura

    In
    
    int Bianca(struct attributo *numero,int &inbyte)
    
    numero è un puntatore;
    in
    
    int Bianca(struct attributo &numero,int &inbyte)
    
    numero è un oggetto e non puoi deallocare un oggetto.
    E la cosa dovrebbe essere chiara dato che con i puntatori si deve usare -> per accedere ai membri, mentre con gli oggetti si usa il .
    Inoltre valore è un array e devi usare
    
    delete[] numero.valore
    
    per liberare la memoria.
    E attribbuto è un int non un puntatore: devi usare 0, non NULL. Sono concetti diversi.
    Se non ricordo male usi VS2012 che dovrebbe avere nullptr per annullare i puntatori, ed evita errori concettuali come questo.
  • Re: Errore C2679 su allocazione di struttura

    Si ho il vs2012 e tu sei quello che mi ha aiutato ad utilizzarlo, te ne sono grato, e che secondo me dovrebbe scrivere una guida sul suo utilizzo che sarebbe migliore di quelle della microsoft.
    ho capito la differenza tra i 2 metodi almeno credo!
    adesso però ad ogni punto che utilizzo numero.valore mi da questo errore
    :\classe numerica\test\bianca.cpp(39): error C2228: l'elemento a sinistra di '.valore' deve avere una classe, struttura o unione
    1> il tipo è 'attributo *'
    1> si intendeva utilizzare '->'?
    
                try { numerox.valore = new char[inbyte];
                        numero.valore = numerox.valore;// qui mi da errore
                    }
    
    se invece faccio:
    
                try { numero.valore = new char[inbyte]; // qui mi da errore
                    }
    
    e come se numero per lui non fosse una struttura invece lo è!
    x il prototipo ho usato quello che mi hai consigliato.
  • Re: Errore C2679 su allocazione di struttura

    Quale dei due prototipi? quello con puntatore o quello con reference? In ambedue i casi, per come lo hai definito, numerox è un puntatore per cui dev'essere
    
    numerox->valore = new char[inbyte]
    
    Meglio se riposti il codice completo, anche perché si potrebbe migliorare.
  • Re: Errore C2679 su allocazione di struttura

    Si andava messa la freccia
         int Bianca(struct attributo *numero,int &inbyte)
                {
                  int dime, modalita, errore, indy;
                  if ( inbyte==0 ) { errore=42; return errore; }
                  dime=0; modalita=0; indy=0; errore=0;
                  sub_attributo sattrib;
                  try { attributo *numerox = new attributo; numero = numerox; }
                  catch ( bad_alloc &err)
                       { numero = nullptr; errore=105; }
                  try { numerox.valore = new char[inbyte];
                        numero->valore = numerox.valore;//new char[inbyte];
                    }
                  catch (bad_alloc &err)
                       { numero->valore = nullptr;//;
                       delete numero;
                       errore=105; }
                  modalita=0;
                  errore=Modifica_Attribbuto(numerox,modalita,sattrib,dime);
                  if (errore !=0)
                    {
    //                  for (indy=0;indy<inbyte;indy++)
      //                   {         }
                           delete[] numero->valore;
                      delete numero;
                      return errore;
                    }
                  for ( indy=0;indy<inbyte;indy++) { numero->valore="0"; }
                  return errore;
    mi parlavi che la gestione del try catch poteva andare in errore
    come posso migliorarla?
    secondo te se faccio una cosa del genere
    
    switch (opzione) // sarebbe un nuovo parametro
    {
    case 0: le due allocazioni che ho scritto prima con la chiusura con il break
    case 1:
    { delete [] numero->valore;
          try { numerox.valore = new char[inbyte];  numero->valore = numerox.valore;  }
                  catch (bad_alloc &err)
                       { numero->valore = nullptr;//;
                       delete numero;
                       errore=105; }
                       break;
    }
    default: restituisce un errore
    }
    
    va bene oppure succede qualche casino perchè in questa modalità alloco solo una parte della struttura e non tutta?
  • Re: Errore C2679 su allocazione di struttura

    Devo spezzarlo in due. Nel primo ti commento la tua funzione e poi metto quel che farei io.
    
    int Bianca(struct attributo *numero, int &inbyte)
    {
    	int dime, modalita, errore, indy;
    	if (inbyte == 0) { errore = 42; return errore; }
    	dime = 0; modalita = 0; indy = 0; errore = 0;
    	sub_attributo sattrib;
    	// questo deve essere esterno ai blocchi.
    	attributo *numerox = nullptr; 
    	try {
    		// Tenicamente questa cosa è rindondante
    		// dato che puoi allocare direttamente numero.
    		// Da notare che l'allocazione resta interna alla funzione
    		// e non viene trasmessa all'esterno. Se l'intenzione
    		// è questa allora il parametro numero non serve a nulla.
    		numerox = new attributo;
    		numero = numerox;
    	}
    	catch (bad_alloc &err)
    	{
    		// qui annulli il puntatore, ma da altre parti non lo fai.
    		numero = nullptr; 		
    		errore = 105;
    		// Grave errore! Se ti trovi qui, significa che non puoi
    		// proprio continuare.
    		return errore;
    	}
    	try {
    		// rindondante ma corretta.
    		numerox->valore = new char[inbyte];
    		numero->valore = numerox->valore;//new char[inbyte];
    	}
    	catch (bad_alloc &err)
    	{
    		numero->valore = nullptr; //;
    		delete numero;
    		// Grave errore! Se ti trovi qui, significa che non puoi
    		// proprio continuare.
    		errore = 105;
    		return errore;
    	}
    	modalita = 0;
    	errore = Modifica_Attribbuto(numerox, modalita, sattrib, dime);
    	if (errore != 0)
    	{
    		delete[] numero->valore; 
    		delete numero; 
    		return errore;
    	}
    
    	for (indy = 0; indy < inbyte; indy++) { numero->valore = "0"; }
    	return errore;
    }
    
  • Re: Errore C2679 su allocazione di struttura

    La mia versione sarebbe:
    
    // inbyte non viene modificato dalla funzione, quindi passarlo
    // per reference non da vantaggi. 
    // Inoltre il contesto di chiamata non è chiaro. Quello
    // che ricevo può essere un puntatore libero oppure un indirizzo 
    // a un oggetto sullo stack della funzione chiamante.
    // Assumo che se numero == nullptr, la funzione chiamante 
    // invii un puntatore libero e non un indirizzo di struttura.
    // Nel primo caso se devo portare le modifiche fuori dalla funzione
    // devo passare un reference al puntatore della struttura.
    // Nel secondo caso non sarebbe necessario, ma usare comunque 
    // un reference al puntatore mi permette di gestire i due casi.
    int Bianca(struct attributo*& numero, int inbyte)
    {
    	int dime, modalita, errore, indy;
    	// assumo che se numero == nullptr, ho
            // un puntatore libero
            bool su_stack = numero != nullptr;
    
    	if (inbyte == 0) { 
    		errore = 42; 
    		return errore; 
    	}
    	dime = 0; modalita = 0; indy = 0; errore = 0;
    	sub_attributo sattrib;
    	try { 
    		// Se l'indirizzo numero non è un indirizzo
    		// dello stack della funzione chiamante e dato
    		// che ricevo un reference al puntatore
    		// posso allocare direttamente il puntatore.
    		// Uso la versione nothrow di new (che non lancia
    		// eccezioni) perché devo avere un indirizzo valido. 
    		if (!su_stack) {
    			numero = new (std::nothrow) attributo;
                            if (!numero) {
                            // allocazione fallita. Esco.
                                return 105; // codice d'errore
                            }
                     }
    		// Questa allocazione la faccio con versione
    		// "classica" di new perché se viene lanciata 
                    // un'eccezione bad_alloc() tutto dev'essere 
                    // invalidato.
    		numero->valore = new char[inbyte];
    
    		modalita = 0;
    		// la funzione può lanciare eccezioni?
    		errore = Modifica_Attribbuto(numero, modalita, sattrib, dime);
    		for (indy = 0; indy < inbyte; indy++) { numero->valore[indy] = '0'; }
    
    	} catch (bad_alloc &err) {
    		// numero->valore ha lanciato l'eccezione.
    		if (!su_stack) {
                            // la ragione di new (std::nothrow)
    			delete numero;
    			numero = nullptr;
    		}
    		errore = 105;
    	}
    	return errore;
    }
    
    Che posso usare così:
    
    int main() {
    	// primo contesto di chiamata.
            // attrib è un puntatore libero. 
            attributo *attrib = nullptr;
    	Bianca(attrib, 16);
    
    	// secondo contesto di chiamata.
            // attrib è un oggetto sullo stack. 
            attributo attrib2;
    	Bianca(&attrib2, 16);
    }
    
  • Re: Errore C2679 su allocazione di struttura

    Allora il fatto che prima alloco in numerox e poi mi copio il risultato in numero è dovuto al prototipo e alla routine Modifica_Attribbuto
    perchè :
    int Bianca(struct attributo *numero,int &inbyte)
    mentre Modifica_Attribbuto
    extern "C" int _stdcall Modifica_Attribbuto(struct attributo &record,int &modalita,struct sub_attributo &record2,int &dime);
    e quando gli vado a passare direttamente numero la procedura va in errore.
    mentre passandogli la copia numerox evito l'errore.
    il fatto che inbyte sia passata per reference è dovuto al fatto che in assembler conviene più passarle per reference che come costanti.
    e la routine sarà chiama da una funzione Assembler che dovrà calcolare il giusto valore. ma questa è un altra storia!
    allora ricapitolando la funzione dovrebbe essere fatta cosi:
    int Bianca(struct attributo *numero,int &inbyte)
                  int dime, modalita, errore, indy;
                  if ( inbyte==0 ) { errore=42; return errore; }
                  dime=0; modalita=0; indy=0; errore=0;
                  bool su_stack = numero !=null ptr;
                                sub_attributo sattrib;
                  // metto le inizializzazioni di sattrib
                  sattrib.inbyte= (int8_t)inbyte; // a proposito va bene come conversione da int a int_8? 
                  attributo numerox;
                  try {
                        if ( !su_stack) 
                          { numero = new (std::nothrow) attributo;
                             if (!numero) { return 105; }
                          }
                       }
                   try {  numero->valore = new char[inbyte];    }
                   catch (bad_alloc &err)
                          { if (!su_stack) { delete numero; numero=nullptr; }
                            errore=105;
                           } 
                           return errore;
                   }
                    modalita=0; 
                    numerox=numero; // cosi dovrei rispettare il reference della funzione modifica_Attribbuto
                    errore = Modifica_Attribbuto(numerox,modalita, sattrib,dime);
                    if (errore !=0)  { delete[] numero->valore;  delete numero; numero=nullptr; numero->valore=nullptr;  }
                  
    se volessi ampliare la funzione immettendo un nuovo parametro int &opzione
    con 0 allocherebbe sia numero che numero.valore
    con 1 allocherebbe solo numero.valore
    <0 o >1 errore
    andrebbe bene fatta in questa maniera?
     
     case 0: // l' allocazione come e fatta di sopra
     case 1: { if (numero==nullptr) { errore=???; break; }
     numerox->valore = numero->valore; // conservo il vecchio vettore;
     try { numero->valore = new char[inbyte]; } // provo ad allocare il nuovo vettore
     catch (bad_alloc &err)
     { numero->valore = numerox->valore; errore=YYY;break; } // c'è errore rimetto le cose come stavano prima
      delete [] numerox->valore; // le cose sono andate bene dealloco il vecchio vettore.
    
  • Re: Errore C2679 su allocazione di struttura

    Scusa, ma compili ogni tanto per vedere che succede? Perché in tutta la discussione avresti dovuto avere una marea di errori fenomenale.
    
    numerox=numero; // cosi dovrei rispettare il reference della funzione modifica_Attribbuto
    
    Così non rispetti proprio niente! Stai cercando di assegnare un puntatore a un oggetto fatto e finito. Errore!
    Semmai alla funzione puoi passare:
    
    errore = Modifica_Attribbuto(*numero,modalita, sattrib,dime);
    
    evitando del tutto numerox.
    
    sattrib.inbyte= (int8_t)inbyte; // a proposito va bene come conversione da int a int_8? 
    
    int8_t in VC++ è un typedef di char. Se la cosa ti sta bene, fallo.
    
     try {  numero->valore = new char[inbyte];    }
    
    Questo try non centra niente. Toglilo.
    il fatto che inbyte sia passata per reference è dovuto al fatto che in assembler conviene più passarle per reference che come costanti.
    Conviene in fatto di tempo? E quanto si risparmia? Due, tre picosecondi? Andiamo...
    andrebbe bene fatta in questa maniera?
    Per come la vedo scritta: no.
Devi accedere o registrarti per scrivere nel forum
37 risposte