1

I'm having a problem with the following program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Persona {
    char *nombre, *apellido;
    int edad;
};

int main(int argc, char const *argv[])
{
    int total_personas = 0;
    printf("Cuantas personas vas a ingresar?\n");
    scanf("%d", &total_personas);

    struct Persona *personas;

    personas = (struct Persona *) malloc(total_personas * sizeof(struct Persona));

    for (int i = 0; i < total_personas; i++) {
        char nombre[256], apellido[256];
        int edad;
        printf("Nombre: ");
        scanf("%s", nombre);
        printf("Apellido: ");
        scanf("%s", apellido);
        printf("Edad: ");
        scanf("%d", &edad);
        struct Persona p = {nombre, apellido, edad};
        personas[i] = p;
    }
    printf("Id\tNombre\tApellido\tEdad\n");
    for (int i = 0; i < total_personas; i++) {
        printf("%d\t%s\t%s\t%d\n",
        i + 1, personas[i].nombre, personas[i].apellido, personas[i].edad);        
    }

    return 0;
}

Basically what I want it to do is the following:

  1. I want to declare a dynamic array of Persona structs.
  2. Then I want to capture the information from the user using scanf
  3. Then I want to display the captured information back to the user.

1 & 2 work "fine". The problem is that my last nombre and apellido (of char[256] each) are overriding my first two inputs:

This is what it shows:

Cuantas personas vas a ingresar?
2 
Nombre: alan
Apellido: chavez
Edad: 32
Nombre: jaun
Apellido: perez
Edad: 54
Id      Nombre  Apellido        Edad
1       jaun    perez   32
2       jaun    perez   54

This is what it should be:

Cuantas personas vas a ingresar?
2 
Nombre: alan
Apellido: chavez
Edad: 32
Nombre: jaun
Apellido: perez
Edad: 54
Id      Nombre  Apellido        Edad
1       alan    chavez   32
2       jaun    perez   54

It only works for the variable edad and I'm not really sure why. Any pointers in the right direction would be greatly appreciated.

When I try to use the strncpy function I get Segmentation fault: 11

This is how I'm using it:

        printf("Nombre: ");
        scanf("%s", nombre);
        strncpy(personas[i].nombre, nombre, strlen(nombre));
ILikeTacos
  • 17,464
  • 20
  • 58
  • 88
  • Does this answer your question? [Why do my string values get overwritten?](https://stackoverflow.com/questions/48378100/why-do-my-string-values-get-overwritten) – Retired Ninja Dec 29 '19 at 22:14
  • Kind of but when i use `strncpy` to copy the values from the variable to the pointer I get `Segmentation fault: 11` – ILikeTacos Dec 29 '19 at 22:17
  • Obligatory link to [Do I cast the result of `malloc`?](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858) – kopecs Dec 29 '19 at 22:40

1 Answers1

1

You store pointers to variables with block scope, i.e. they go out of scope and must not be accessed once the block (in the for-loop) has finished; accessing these pointers later is undefined behaviour.

In your case, the input is probably written to the same memory space, such that the second input overrides the first one; And all your pointers probably point to the same memory address.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • Thanks for your answer, although i understand what you're saying I do not fully understand how to fix it. – ILikeTacos Dec 29 '19 at 22:25
  • 1
    "struct Persona p = {strdup(nombre), strdup(apellido), edad};” should do it, but really it is better to check for failures (strdup calls malloc which can fail), etc... – mevets Dec 29 '19 at 22:35
  • 2
    @ILikeTacos instead of having each struct live on the stack, you could instead `malloc` them, and have an "array" of pointers. (as to why I've quoted array, what you have isn't *really* an array, at least as the standard defines it: [see here](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays)) – kopecs Dec 29 '19 at 22:39
  • Thank you so much I get it now! – ILikeTacos Dec 29 '19 at 22:40