Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [C++] Problema lettura con overload operatore >> e stringhe dinamiche

    Ho una classe con 2 variabili char *, quando vado a inizializzarle tramite l'operatore >> mi stampa una stringa che non corrisponde a quella che inserisco. Tuttavia, quando stampo C.nome all'interno della funzione stessa, la stringa è corretta, è nel main che viene cambiata. Questo succede solo con le var char *, l'int per esempio non viene cambiato.

    cliente.h
    codice:
    class cliente{
          private:
                  char * nome;
                  char * cognome;
                  int eta;
                  int test[3];
                  
                  //overload << e >>
                  friend ostream& operator<<(ostream &,const cliente &);
                  friend istream& operator>>(istream &,cliente &);
                 
          public:             
                   //funzioni varie
    cliente.cpp
    codice:
    istream& operator>>(istream& in,cliente& C){
             buffer app;
             char * capp;
             
             cout << "Inserisci nome:\n";
             in >> app;
             alloca(capp,app);
             C.nome=capp;
             cout << capp << endl;
             cout << C.nome << endl;
             cout << "Inserisci cognome:\n";
             in >> app;
             alloca(capp,app);
             C.cognome=capp;
             cout << "Inserisci eta:\n";
             in >> C.eta;
             return in;
             }
    allocstr.h //contiene la funzione d'allocazione
    codice:
    void alloca(char *&s,buffer bf){
         s = new char[strlen(bf)];
         s=bf;
         }
    Qualcuno sa dove mettere le mani?

  2. #2
    Com'è definito buffer? In ogni caso, usare dei char * gestiti direttamente dalla classe in genere è una pessima idea, dovresti usare std::string piuttosto.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Purtroppo la traccia impone chiaramente che le stringhe devono essere allocate dinamicamente.
    Il buffer è così dichiarato:
    codice:
    typedef char buffer[256];
    Edit: Credo di aver capito qual'è il problema ma non so come risolverlo.
    Alla fine dell'overloading faccio "return in;", quindi passo tutto ciò che inserisco tramite in >>
    Il problema sta nel fatto che faccio in >> variabile_appoggio; e poi C.nome=variabile_appoggio;
    Inoltre non posso fare direttamente in >> C.nome; in quanto il programma crasherebbe...
    idee?

  4. #4
    Originariamente inviato da nostradamus1915
    Purtroppo la traccia impone chiaramente che le stringhe devono essere allocate dinamicamente.
    std::string internamente usa stringhe allocate dinamicamente; il problema del tuo approccio è che gestendo manualmente la memoria nella classe ti ritrovi a ripetere un sacco di codice di gestione delle stringhe inutilmente, rendendo più complicato il codice della classe e violando il SRP. Comunque, se la traccia impone che sia così...
    Edit: Credo di aver capito qual'è il problema ma non so come risolverlo.
    Alla fine dell'overloading faccio "return in;", quindi passo tutto ciò che inserisco tramite in >>
    Il problema sta nel fatto che faccio in >> variabile_appoggio; e poi C.nome=variabile_appoggio;
    Inoltre non posso fare direttamente in >> C.nome; in quanto il programma crasherebbe...
    idee?
    Non ho ben capito perché tutto questo sia un problema... piuttosto, l'errore sta in alloca:
    codice:
    void alloca(char *&s,buffer bf){
         s = new char[strlen(bf)];
         s=bf;
         }
    s è un reference ad un char * (idea bizzarra, tra l'altro ), per cui:
    - prima allochi della memoria per la nuova stringa (tra l'altro, devi allocare strlen(bf)+1 caratteri, dato che devi tener conto anche del carattere di fine stringa) e assegni la memoria così allocata a s;
    - poi sovrascrivi il puntatore s, facendolo puntare a bf (che di fatto non è altro che un puntatore alla memoria fornita da app, visto che i parametri di tipo array in C++ di fatto vengono passati come puntatori); per questo, al termine della funzione sia C.nome che C.cognome puntano a della memoria che non esiste più (dato che app è locale a operator>>).

    Una versione corretta di alloca sarebbe:
    codice:
    void alloca(char *&s,buffer bf){
         s = new char[strlen(bf)+1];
         strcpy(s, bf);
         }
    o più banalmente potresti usare strdup (nota che però con quest'ultima per liberare la memoria devi usare free).

    Ma, di nuovo, il modo corretto è usare std::string:
    codice:
    class cliente{
          private:
                  std::string nome;
                  std::string cognome;
                  int eta;
                  int test[3];
                  // ...
    codice:
    istream& operator>>(istream& in,cliente& C){
             cout << "Inserisci nome:\n";
             in >> C.nome;
             cout << C.nome << endl;
             cout << "Inserisci cognome:\n";
             in >> C.cognome;
             cout << "Inserisci eta:\n";
             in >> C.eta;
             return in;
             }
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Chiarissimo grazie!

  6. #6
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.