elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  (Consulta) Problema con un arreglo dinamico
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: (Consulta) Problema con un arreglo dinamico  (Leído 1,768 veces)
palacio29

Desconectado Desconectado

Mensajes: 103


Ver Perfil
(Consulta) Problema con un arreglo dinamico
« en: 31 Mayo 2019, 01:04 am »

Tengo el siguiente ejercicio que no se que es lo que esta fallando.  :huh:
Tengo una estructura  en la cual tengo:

- Una variable int que carga el legajo de un alumno (un numero cualquiera)
- Un puntero char, en donde se va a guardar el nombre del alumno (Ejemplo Juan)
- Un unsigned char en donde se guarda el codigo de una materia. (Ejemplo CATEGORIA B).

En el main lo que hago es cargar un arreglo estatico de esta estructura.
Lo que tengo que hacer con la funcion filtrar es crear un arreglo dinamico que cree e incluya los valores del arreglo estatico que tengan la categoria B.
No se cual es el error, pensaba que era algo de memoria dinamica que estaba fallando, pero puse una memoria grande e igualmente el programa falla.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4. #define T 3
  5. struct s_alumno
  6. {
  7.    unsigned int leg;
  8.    char*nombre;
  9.    unsigned char cod_car;
  10. };
  11. typedef struct s_alumno t_alumno;
  12. t_alumno* filtrar(t_alumno arr[T],char cod_car);
  13. void IMPRIMIR(t_alumno*);
  14.  
  15. int main()
  16. {
  17.    t_alumno arr[T];
  18.    int i=0;
  19.    char letra;
  20.    t_alumno* listado=NULL;
  21.    arr[0].nombre="Fabian";
  22.    arr[1].nombre="Pablo";
  23.    arr[2].nombre="Manuel";
  24.    while(i<T)
  25.    {
  26.        printf("\nCARGAR NUMERO LEGAJO:\n ");
  27.        scanf("%d",&arr[i].leg);
  28.        printf("CARGAR CODIGO CARRERA\n");
  29.        letra=getche();
  30.        arr[i].cod_car=letra;
  31.        i++;
  32.    }
  33.    printf("\n");
  34.    printf("El nombre cargado es %s - CODIGO DE CARRERA: %c\n",arr[0].nombre,arr[0].cod_car);
  35.    printf("El nombre cargado es %s - CODIGO DE CARRERA: %c\n",arr[1].nombre,arr[1].cod_car);
  36.    printf("El nombre cargado es %s - CODIGO DE CARRERA: %c\n",arr[2].nombre,arr[2].cod_car);
  37.    listado=filtrar(arr,'B');
  38.    IMPRIMIR(listado);
  39.  
  40.    return 0;
  41. }
  42.  
  43.  
  44. t_alumno* filtrar(t_alumno arr[T],char cod_car)
  45. {
  46.    int i=0,j=0,fin=0;
  47.    t_alumno*lista=NULL;
  48.    lista=malloc(sizeof(struct s_alumno));
  49.    while(i<T)
  50.    {
  51.        if((cod_car)==arr[i].cod_car)
  52.        {
  53.            (lista+j)->leg=arr[i].leg;
  54.            strcpy((lista+j)->nombre,arr[i].nombre);
  55.            (lista+j)->cod_car=arr[i].cod_car;
  56.            j++;
  57.           lista=realloc(lista,(j+1)*sizeof(struct s_alumno));
  58.        }
  59.        i++;
  60.    }
  61.    (lista+j)->leg=0;
  62.    printf("\nTERMINO EL FILTRADO\n");
  63.    return lista;
  64.  
  65. }
  66.  
  67. void IMPRIMIR(t_alumno* listado)
  68.  
  69. {
  70. int i=0;
  71. printf ("\nIMPRESION DEL ARREGLO\n");
  72. while(listado[i].leg!=0)
  73. {
  74.     printf("NOMBRE: %s - CODIGO DE CARREA: %c\n",(listado+i)->nombre,(listado+i)->cod_car);
  75.     i++;
  76. }
  77. }
  78.  


« Última modificación: 31 Mayo 2019, 02:24 am por palacio29 » En línea

K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 1.008



Ver Perfil
Re: (Consulta) Problema con memoria dinamica y arreglo estructuras
« Respuesta #1 en: 31 Mayo 2019, 02:20 am »

Varias cosas... Primero sobre los nombres. Al usar cadenas literales no estás reservando memoria en cada <struct> para guardar los nombres. Lo que estás haciendo es que los punteros del <struct> apunten a la dirección de memoria en la que se encuentran esas cadenas almacenadas desde antes de la ejecución del programa.
Entonces a la hora de crear la nueva lista con el filtro, no puedes copiar los nombres usando <strcpy()> puesto que tampoco estás reservando memoria para estos. Lo único que puedes hacer es hacer que los punteros a <char> de las nuevas <struct> apunten a las mismas cadenas literales.

Ahora sobre el <realloc()>. Si no reservas memoria con <malloc()> (cosa que no deberías hacer) lo único que tienes es un puntero a <t_alumno>. Entonces para "insertar" un nuevo <t_alumno> tendrás que hacer el <realloc()> antes, no después.

Para saber cuántos <t_alumno> hay en el filtro yo usaría otro parámetro por referencia para contabilizarlos y así no tener que poner el último <leg> a 0.
Código
  1. t_alumno* filtrar(t_alumno *arr, char cod_car, size_t *num_filtrados){
  2. t_alumno *filtro = NULL; // tenemos un array vacio
  3. *num_filtrados = 0;
  4.  
  5. for(size_t i = 0; i < SIZE; ++i){
  6. if(arr[i].cod_car == cod_car){ // si son iguales...
  7. (*num_filtrados)++; // ...tenemos un elemento mas en el filtro...
  8. filtro = (t_alumno*) realloc(filtro, *num_filtrados * sizeof(t_alumno)); // ...y reservamos memoria para introducirlo
  9. filtro[*num_filtrados-1].leg = arr[i].leg;
  10. filtro[*num_filtrados-1].nombre = arr[i].nombre; // hacemos que apunte al mismo sitio que arr[i].nombre, no copiamos la cadena porque no hay memoria
  11. filtro[*num_filtrados-1].cod_car = arr[i].cod_car;
  12. }
  13. }
  14. printf("\nTERMINO EL FILTRADO\n");
  15. return filtro;
  16. }


En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines