es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo almacenar un valor en un array de una estructura en C

Tengo una estructura como esta:

struct student {

<pre><code>char name[50];
int grade;
</code></pre>

<p>};
<code>
Quiero crear un array de estructuras (una por cada estudiante, usando malloc).
</code>
 struct student <em>studs=malloc(STUDENT_NUM</em>sizeof(struct student));

Después de eso recorrí mis arrays que contienen la información de los estudiantes y luego intenté almacenar esa información en cada estructura. Hasta ahora, me aparece un fallo de segmentación pero no entiendo por qué.


for(int i=0;i<STUDENT_NUM;i++){
strcpy(Names[i],studs[i].name);
studs[i].grade=Grades[i];
}

Encontré otro enfoque, que funciona, pero solo quiero saber cómo puedo hacer que funcione usando la estructura anterior.

Así que la “solución que encontré en realidad consiste en cambiar el campo de la estructura a:

char name;

Y luego en el bucle simplemente asigno espacio para ese array así:

studs[i].name=malloc(50
sizeof(char));

¿Por qué mi primer enfoque me da un fallo de segmentación? ¿No he asignado memoria al utilizar esa inicialización char name[50];?
**También a tener en cuenta que estoy aprendiendo C (por si no era obvio).
Gracias de antemano.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La razón por la que estás obteniendo un error de segmentación en tu primer enfoque es porque no estás asignando memoria para el campo name de tu estructura struct student. Cuando declaras char name[50], estás asignando espacio para un array de caracteres de 50 elementos en la pila, pero esta memoria no es accesible por la función malloc. Entonces, cuando intentas copiar el nombre desde tu array de entrada a studs[i].name, estás intentando escribir en memoria que no ha sido reservada por malloc, lo cual resulta en un error de segmentación.

    Para solucionarlo, puedes asignar memoria para el campo name de cada estructura struct student usando malloc, de la misma forma en que lo hiciste para el array de estudiantes. Una forma de hacer esto sería modificar tu bucle de la siguiente manera:

    for (int i = 0; i < STUDENT_NUM; i++) {
        // Asignar memoria para el campo name de cada estudiante
        studs[i].name = malloc(50 * sizeof(char));
    
        // Copiar el nombre y la calificación en cada estructura
        strcpy(studs[i].name, Names[i]);
        studs[i].grade = Grades[i];
    }
    

    En este bucle actualizado, estamos asignando memoria para el campo name de cada struct student usando malloc, luego estamos copiando el nombre y la calificación desde nuestros arrays de entrada a la correspondiente struct student. Esto debería prevenir el error de segmentación que estabas experimentando.

    Alternativamente, podrías cambiar el campo name de tu struct student a un char*, como lo hiciste en tu segundo enfoque, y asignar memoria usando malloc cuando sea necesario. Esto te permitirá asignar solo la cantidad necesaria de memoria para cada nombre, en lugar de reservar la misma cantidad de memoria (50 caracteres) para cada nombre. Sin embargo, deberás recordar liberar esta memoria cuando hayas terminado de usarla.

    // Define tu `struct student` así:
    struct student {
        char* name; // cambiado a char*
        int grade;
    };
    
    // Asigna memoria para el nombre de cada estudiante en tu bucle:
    for (int i = 0; i < STUDENT_NUM; i++) {
        studs[i].name = malloc(strlen(Names[i]) + 1); // + 1 para el terminador nulo
        strcpy(studs[i].name, Names[i]);
        studs[i].grade = Grades[i];    
    }
    
    // Libera la memoria para el nombre de cada estudiante cuando hayas terminado con ella:
    for (int i = 0; i < STUDENT_NUM; i++) {
        free(studs[i].name);
    }
    

    Ten en cuenta que en este caso, necesitas asignar memoria para cada studs[i].name utilizando strlen en lugar de un tamaño fijo, ya que cada nombre puede tener una longitud diferente. También debes recordar liberar cada studs[i].name utilizando free cuando hayas terminado con ella, para evitar fugas de memoria.

Comments are closed.