Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: xJajavierx en 3 Febrero 2020, 08:21 am



Título: Segmentation fault
Publicado por: xJajavierx en 3 Febrero 2020, 08:21 am
Hola, alguien me podría ayudar a solucionar este "problema" de segmentation fault por favor

Este es el codigo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <string.h>
  5. typedef struct alumno
  6. {
  7.    int matricula;
  8.    int promedio;
  9. }T_alumno;
  10. int aleatorio20(int &cant);
  11. int promedio10(int &prom);
  12. int matricula(int &matr);
  13. void iniciar_arreglo_alumnos(T_alumno *arreglo_alumnos, int &cant);
  14. void imprime_arreglo_alumnos(T_alumno *arreglo_alumnos, int &cant, int &prom, int &matr);
  15. int main()
  16. {
  17.    srand(time(NULL));
  18.    int cant, prom, matr;
  19.    T_alumno *arreglo_alumnos;
  20.    aleatorio20(cant);
  21.    promedio10(prom);
  22.    matricula(matr);
  23.    iniciar_arreglo_alumnos(arreglo_alumnos,cant);
  24.    imprime_arreglo_alumnos(arreglo_alumnos,cant,prom,matr);
  25.    return 0;
  26. }
  27. int aleatorio20(int &cant)
  28. {
  29.    cant=5+rand()%26;
  30. }
  31. int promedio10(int &prom)
  32. {
  33.    prom=rand()%11;
  34. }
  35. int matricula(int &matr)
  36. {
  37.    matr=124+rand()%77;
  38. }
  39. void iniciar_arreglo_alumnos(T_alumno *arreglo_alumnos, int &cant)
  40. {
  41.    arreglo_alumnos=new T_alumno[cant];
  42. }
  43. void imprime_arreglo_alumnos(T_alumno *arreglo_alumnos, int &cant, int &prom, int &matr)
  44. {
  45.    for(int i=0;i<cant;i++)
  46.    {
  47.        promedio10(prom);
  48.        arreglo_alumnos[i].promedio=prom;
  49.        matricula(matr);
  50.        arreglo_alumnos[i].matricula=matr;
  51.    }
  52.    for(int i=0;i<cant;i++)
  53.    {
  54.        printf("Promedio %i: %d",i+1,arreglo_alumnos[i].promedio);
  55.        printf("Matricula %i: 123%d",i+1,arreglo_alumnos[i].matricula);
  56.    }
  57. }


Título: Re: Segmentation fault
Publicado por: Eternal Idol en 3 Febrero 2020, 12:29 pm
Primero el codigo no compila (aunque por el error que ves entiendo que el problema es de copiar y pegar) y segundo arreglo_alumnos siempre va a tener un valor indefinido.

(23) : warning C4700: uninitialized local variable 'arreglo_alumnos' used
    iniciar_arreglo_alumnos(arreglo_alumnos,cant);

Aca:
Código
  1. void iniciar_arreglo_alumnos(T_alumno *arreglo_alumnos, int &cant)
  2. {
  3.    arreglo_alumnos=new T_alumno[cant];
  4. }

arreglo_alumnos es simplemente una variable LOCAL (al estar pasandola por valor y no por referencia) y la asignacion se pierde en cuanto salis del ambito de la funcion. O pasas doble puntero o puntero por referencia para poder efectivamente asignarle el valor a la variable declarada en main AL TENER LA DIRECCION DEL MISMO EN iniciar_arreglo_alumnos y no a donde apunta (que en tu caso es a cualquier lado al no estar inicializada la variable).

Código
  1. T_alumno *arreglo_alumnos;
  2. printf("%p\n", arreglo_alumnos);
  3. aleatorio20(cant);
  4.    promedio10(prom);
  5.    matricula(matr);
  6.    iniciar_arreglo_alumnos(arreglo_alumnos,cant);
  7. printf("%p\n", arreglo_alumnos);
  8.  

Asi veras con claridad como iniciar_arreglo_alumnos no hace nada util.


Título: Re: Segmentation fault
Publicado por: CalgaryCorpus en 6 Febrero 2020, 13:58 pm
El codigo parece tener varias cosas que se pueden remover.

La funcion iniciar_arreglo_alumnos ademas de no servir el proposito, no parece ser necesaria. Eliminala, reemplaza su invocacion por la peticion explicita de memoria.

Las variables prom y matr en el main no tienen sentido definirlas alli, pues cambian su valor, pero no se usan al interior de la funcion. Definelas al interior de la funcion imprimir.

Pareciera mejor tener otra funcion que asigne esos valores y que la funcion imprimir solo muestre estos valores. No se ve bien que una funcion encargada de imprimir asigne los valores tambien.

Las funciones aleatorio20, matricula y promedio10 dicen retornar int, pero no retornan nada. Podrias en vez de modificar el parametro que reciben, borrar el parametro que reciben, que no reciban nada, y hacer return del valor que calculan. Con esto incluso no vas a necesitar las variables locales prom y matr, puedes asignar lo retornado directamente a los campos (lineas 47 y siguientes).