Problems when storing strings of a class in an array

1

My program consists of a menu that has:

  • Register.
  • Unsubscribe.
  • Modify.
  • Show.
  • Exit.
  • And the Person class with its constructors and methods.

    The Person class is something like this:

    Class Persona{
    private:
    char* dni;
    char* nombreCompleto;
    int edad;
    
    public:
    Persona(char*, char*, int);
    ~Persona();
    //Métodos accedentes y mutadores, y visualizar datos
    };
    

    and the constructor:

    Persona::Persona(char* dni, char* nombreCompleto, int edad){
    this->dni = dni;
    this->nombreCompleto = nombreCompleto;
    this->edad = edad;
    
    }
    

    When pressing 1 we ask for the data:

    char id[MAX_DNI], nC[MAX_NOMBRE];
    int anios;
    cout << "Introduzca el dni: ";
    cin >> id;  
    cin.ignore();
    cout << "Introduzca su nombre completo: ";
    cin.getline(nC, MAX_NOMBRE);
    cout << "Introduzca la edad: ";
    cin >> anios;
    

    Then we create the object:

    Persona persona1 = Persona(id, nC, anios);
    

    After creating the object persona1 we call a function that stores that object in the array. So far so good. The problem comes when I re-register another person, the data of the first person with characters is modified.

    Example:

    We register the first person and print:

    DNI: XXXXXXXXX
    Nombre: Fulanito
    Edad: 34
    

    We re-register another person, by pressing 1:

    DNI: YYYYYYYYY
    Nombre: Pepe
    Edad: 22
    

    And when printing all the elements of the array print this:

    Persona 1:
    DNI: YYYYYYYYY
    Nombre: Pepe
    Edad: 34
    
    Persona 2: 
    DNI: YYYYYYYYY
    Nombre Pepe
    Edad: 22
    

    The DNI and the name of the first person are changed to the name of the second person but the age has remained intact.

    Do you know why this happens? I have also tried to destroy the generated object once the information is entered into the array but it does not work either. I hope you have understood me more or less and thank you very much!

        
    asked by Onironaut 03.05.2018 в 12:46
    source

    1 answer

    4

    Note that nC is a pointer;

    char id[MAX_DNI], nC[MAX_NOMBRE];
    //                ^^ puntero
    

    And when creating the object you pass to the constructor said pointer:

    Persona persona1 = Persona(id, nC, anios);
    //                             ^^ AQUI
    

    And the Persona constructor is limited to keeping a copy of the pointer:

    Persona::Persona(char* dni, char* nombreCompleto, int edad){
      this->dni = dni;
      this->nombreCompleto = nombreCompleto; // <<---
      this->edad = edad;
    
    }
    

    The problem is that you are not copying the content of the pointer but only the pointer itself. That is, all copies of Persona that you make will point to the same region of memory, then all will share the name (and the same happens with the DNI)

    The basic solution is not copying pointers but copying the data to which it points:

    Class Persona{
    private:
      char dni[MAX_DNI];
      char nombreCompleto[MAX_NOMBRE];
    };
    
    Persona::Persona(char* dni, char* nombreCompleto, int edad){
      strcpy(this->dni,dni);
      strcpy(this->nombreCompleto,nombreCompleto);
      this->edad = edad;
    }
    

    Although you will always have the cleanest code if you use std::string instead of character arrays:

    Class Persona{
    private:
      std::string dni;
      std::string nombreCompleto;
    };
    
    Persona::Persona(std::string const& dni, std::string const& nombreCompleto, int edad){
      this->dni = dni;
      this->nombreCompleto = nombreCompleto;
      this->edad = edad;
    }
    
        
    answered by 03.05.2018 / 13:38
    source