Errore C2679 su allocazione di struttura

di il
37 risposte

37 Risposte - Pagina 2

  • Re: Errore C2679 su allocazione di struttura

    Adesso non posso compilarlo perchè sto a lavoro e non ho a disposizione il visual c++.
    ma nei tempi morti ci lavoro e quando vado a casa compilo. cosi ottimizzo i tempi!
    levo quella try che non serve
    e come lo dovrei fare il case 1?
    la logica che ho usato è questa:
    verifico se il numero è già attivo se non lo è c'è un errore ed esco
    il numero è attivo e conservo le cifre per evitare che si perdano dati
    provo ad allocare un nuovo vettore per le cifre
    se non ci riesco bad_allocation ripristino i vecchio vettore segnalo l'errore ed esco
    modifico i valori dell'attributo.
    se ci sono errori rimetto tutto a posto come era prima
    altrimenti cancello il vecchio vettore per evitare spreco di memoria.
  • Re: Errore C2679 su allocazione di struttura

    Non è un problema di algoritmo, ma di come è scritto. Tratti oggetti come fossero puntatori e viceversa.
    Tra l'altro potresti allocare quel che ti serve usando new (std::nothrow) evitando giri della morte con i try / catch e migliorando la leggibilità del codice. Ma poi perché vorresti allocare numero dentro Bianca() e non invece farlo fuori?
    Dal mio punto di vista stai facendo dei contorsionismi degni di un acrobata
  • Re: Errore C2679 su allocazione di struttura

    Vorrei allocare numero dentro bianca perchè cosi e più pratico.
    meglio richiamare una sola funzione modificando un parametro che chiamare alternativamente le due funzioni che allocano la struttura o parte di essa.
    proverò a scriverla senza usare i try catch
    e poi la posto cosi mi dici dove sbaglio.
  • Re: Errore C2679 su allocazione di struttura

    Ecco la routine
    in fase di compilazione non ci sono errori
    
             int Bianca(struct attributo *numero,int &inbyte,int &opzione)
                {
                  int dime, modalita, errore, indy;
                  if ( inbyte==0 ) { errore=42; return errore; }
                  dime=0; modalita=0; indy=0; errore=0;
                  sub_attributo sattrib;
                  sattrib.attivo=1; sattrib.segno=0; sattrib.pv=0;
                  sattrib.inbyte = (int8_t)inbyte; sattrib.periodico=0;
                  sattrib.costante=0; sattrib.cripta=0; sattrib.fbcb=0;
                  sattrib.filler=0;
                  attributo numerox;
                  switch (opzione)
                        {
                       case 0:
                           {
                             bool su_stack = numero!=nullptr;
                             if (!su_stack)
                               {
                                 numero = new (std::nothrow) attributo;
                                 if (!numero){ errore=105; break; }
                               }
                                 numero->valore = new char[inbyte];
                              if (!su_stack)
                                {
                                  delete numero; numero=nullptr;
                                  errore=105; break;
                                }
                             modalita=0;
                             errore = Modifica_Attribbuto(*numero,modalita,sattrib,dime);
                             if (errore !=0)
                               {
                                 delete[] numero->valore; delete numero;
                                 numero->valore=nullptr; numero=nullptr;
                               }
                              break;
                           }
                       case 1:
                           {
                             if (numero == nullptr) { errore = 103; break; }
                             numerox.valore=numero->valore;
                             bool su_stack = numero->valore != nullptr;
                             if (!su_stack)
                               {
                                 numero->valore = new (std::nothrow) char[inbyte];
                                 if (!numero->valore)
                                   {
                                     numero->valore = numerox.valore;
                                     errore=105; break;
                                   }
                               }
                             modalita=33; sattrib.inbyte = (int8_t) inbyte;
                             errore = Modifica_Attribbuto(*numero,modalita,sattrib,dime );
                             if (errore !=0)
                               {
                                 numero->valore = numerox.valore;
                                 errore=105; break;
                               }
                             delete [] numerox.valore; break;
                           }
                       default: { errore = 42; break; }
                        }
    
  • Re: Errore C2679 su allocazione di struttura

    Vorrei allocare numero dentro bianca perchè cosi e più pratico.
    Tecnicamente però è scorretto. Dovrebbe essere la routine chiamante a provvedere allo spazio necessario per numero, non la chiamata.
    E comunque la memoria allocata per numero internamente alla routine chiamata, rimane interna alla routine chiamata: fuori da essa hai solo spazzatura. Inoltre chi è che dovrebbe deallocare la memoria? Un'altra routine C++? La regola d'oro è che il lato che alloca memoria deve anche deallocarla.
    Ecco la routine
    in fase di compilazione non ci sono errori
    Il prossimo compito è di risolvere quelli in runtime (se ce ne sono).
  • Re: Errore C2679 su allocazione di struttura

    Beh l'idea era quella!
    vorrà dire che aggiungo altre 2 opzioni così rientro nella regola d'oro.
    ma come codice è decente o pessimo?

    shodan ha scritto:


    E comunque la memoria allocata per numero internamente alla routine chiamata, rimane interna alla routine chiamata: fuori da essa hai solo spazzatura.
    ma mica si perdono i dati?
    scusa ma una volta allocata la memoria non dovrebbe restare a disposizione finchè non si libera?
    come mai un comportamento cosi strambo?
  • Re: Errore C2679 su allocazione di struttura

    ma come codice è decente o pessimo?
    Sicuro di volerlo sapere? Per come la vedo io stai solo rendendo complicato qualcosa di molto semplice.
    1) ma mica si perdono i dati?
    2) scusa ma una volta allocata la memoria non dovrebbe restare a disposizione finchè non si libera?
    3) come mai un comportamento cosi strambo?
    1) finché resti all'interno della funzione, no. Appena ne esci, si.
    2) la memoria resta allocata, ma quel che fai all'interno della funzione è perso appena ne esci.
    3) perché stai lavorando su una copia del puntatore.
    
    int Bianca(struct attributo *numero,int &inbyte,int &opzione)
    
    numero è una copia del puntatore che passi, non è il puntatore che passi.
    C'era il motivo per cui avevo scritto:
    
    int Bianca(struct attributo *&numero,int &inbyte,int &opzione)
    
    Se non ne sei convinto prova a compilare e far girare questo:
    
    struct attributo {
    	int attribbuto;
    	char* valore;
    };
    
    void Test1(struct attributo* p) {
    	p = new attributo;
    	p->attribbuto = 10;
    }
    
    void Test2(struct attributo*& p) {
    	p = new attributo;
    	p->attribbuto = 10;
    }
    
    int main(void) {
    
    	attributo* attr1 = nullptr;
    	attributo* attr2 = nullptr;
    
    	Test1(attr1);
    	Test2(attr2);
                    
     	cout << (attr1 == nullptr) << endl; // true, 1 
    	cout << (attr2 == nullptr) << endl; // false 0;
            
    	delete attr2;
    	delete attr1;
    }
    
    In Test1 allochi memoria che poi sarà persa una volta che la funzione esce, stessa cosa per i vari campi.
    In Test2 le modifiche sono trasmesse alla funzione chiamante.
  • Re: Errore C2679 su allocazione di struttura

    Mi hai sempre dato ottime soluzioni e hai spiegato in maniera chiara.
    perchè non mi dovrei fidare?
    quindì se ho capito bene l'errore che faccio stà nella definizione.
    correggo subito!
  • Re: Errore C2679 su allocazione di struttura

    Adesso il progetto mi da error LNK2001: simbolo esterno _Bianca@12 non risolto
    
    // prototipo:
    extern "C" int _stdcall Bianca(struct attributo *&numero,int &inbyte,int &opzione);
    // definizione
     int Bianca(struct attributo *&numero,int &inbyte,int &opzione)
     // uso
      attributo *numero = nullptr;
    	  numero->valore=nullptr;
    	  altro=10;moda=0;
     errore=Bianca(numero,altro,moda);
    
    compilo con opzione /Gz (conversione di chiamata _stdcall)
    il file lo ho aggiunto e compilandolo non mi da errori.
    ho provato anche a metterci un errore,nel file, e me lo segnalava.
    adesso dove è l'errore?
  • Re: Errore C2679 su allocazione di struttura

    Quando si esporta una funzione libera da una dll o sorgente non C/C++ tramite __stdcall viene anteposto un _ davanti al nome di funzione esportata. pertanto Bianca diventa _Bianca. Per DLL c'è modo di evitarlo, per atri tipi di sorgenti devi consultare la documentazione.
    Però eviterei di modificare la convenzione di chiamata che è globale al progetto, e metterei solo __stdcall davanti alle funzioni che mi interessano.
  • Re: Errore C2679 su allocazione di struttura

    Ma perchè non lo scrivi quel manuale sul uso del visual c++?
    ce ne sono tanti in commercio che sono davvero pessimi!
    un ultime 2 domanda sul argomento di prima (allocazione)
    1)
    nel caso debba allocare una matrice la definizione della funzione deve essere fatta cosi:
    
    int Bianca1(char **&&matrice, int &righe, int &colonne,int &opzione);
    
    oppure
    
    int Bianca1(char *&*&matrice, int &righe, int &colonne,int &opzione);
    
    2) il cuore della funzione andrebbe bene fatto così ?
    
    int errore,indy,kindy,windy;
           errore=0;windy=0;
           indy=righe;
           kindy=colonne;
            bool su_stack matrice != nullptr;
           if (!su_stack) // allocazione vettore delle righe
             {
               matrice = new (char*[indy]);
               if (!matrice)
                 {
                   matrice=nullptr;errore=106;return errore;
                 }
             }       
             
    per quanto riguarda le colonne
    
    // allocazione colonne
               for (windy=0;windy<indy;windy++)
                   {
                     matrice[windy] = new ( char[kindy] );
                     if (!matrice[windy])
                       {
                         matrice[windy]=nullptr;:errore=106;
                         windy=indy; // cosi esco dal ciclo.
                       }
                   }
                return errore;               
    
  • Re: Errore C2679 su allocazione di struttura

    Se devi operare su una matrice la migliore cosa che puoi fare è allocare un unico vettore righe x colonne e lavorare con lo shift degli indici, invece di fare N-mila allocazioni che poi devi gestire se una va male.
    Per la cronaca i prototipi sono sbagliati. Entrambi.
  • Re: Errore C2679 su allocazione di struttura

    Andando per tentativi!
    int Bianca1(char **&matrice, int &righe, int &colonne,int &opzione);
  • Re: Errore C2679 su allocazione di struttura

    Per l'altro problema credo che la soluzione sia: aggiungere un ciclo.
    
    // allocazione colonne
               for (windy=0;windy<indy;windy++)
                   {
                     matrice[windy] = new ( char[kindy] );
                     if (!matrice[windy])
                       {
                        for (int cindy=0;cindy<windy;cindy++)
                            { delete matrice[cindy]; } // dealloca singola cella che andava bene!
                         matrice[windy]=nullptr;:errore=106;
                         windy=indy; // cosi esco dal ciclo.
                       }
                   }
    se non dovesse andare bene allora la soluzione migliore sarebbe il maxvettore.
  • Re: Errore C2679 su allocazione di struttura

    Il maxvettore è sempre la soluzione migliore
    Andando per tentativi!
    Per tentativi? Il C++ non si impara per tentativi, ma studiandolo sui libri!
    Così non vai da nessuna parte.
Devi accedere o registrarti per scrivere nel forum
37 risposte