Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Duda programación en C

Estas en el tema de Duda programación en C en el foro de C/C++ en Foros del Web. Buenas, estoy intentando hacer un código que pida por pantalla el nombre, la edad y el teléfono de una persona para añadirlo a una lista. ...
  #1 (permalink)  
Antiguo 25/06/2015, 08:20
 
Fecha de Ingreso: junio-2015
Mensajes: 4
Antigüedad: 8 años, 10 meses
Puntos: 0
Duda programación en C

Buenas, estoy intentando hacer un código que pida por pantalla el nombre, la edad y el teléfono de una persona para añadirlo a una lista. El código es el siguiente:


Código c:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4.  
  5. struct Datos{
  6.     char *nombre;
  7.     int edad;
  8.     double telef;
  9.     struct Datos *sig;
  10. };
  11.  
  12. typedef struct Datos miembro;
  13.  
  14. miembro *CrearMiembro(miembro *Lista, double telefono, int anios, char *name){
  15.    
  16.     miembro *NuevoMiembro, *aux;
  17.     NuevoMiembro = (miembro *) malloc(sizeof(miembro));
  18.    
  19.     if(NuevoMiembro != NULL){
  20.         NuevoMiembro->edad = anios;
  21.         NuevoMiembro->telef = telefono;
  22.         NuevoMiembro->nombre = name;
  23.         NuevoMiembro->sig = NULL;
  24.     }
  25.    
  26.         if (Lista == NULL){
  27.             Lista = NuevoMiembro;
  28.         }
  29.         else{
  30.             aux = Lista;
  31.            
  32.             while(aux->sig != NULL){
  33.                 aux = aux->sig;
  34.             }
  35.            
  36.             aux = NuevoMiembro;
  37.         }
  38.    
  39.     return Lista;
  40. }
  41.  
  42. void ImprimirLista(miembro *Lista){
  43.    
  44.     miembro *aux;
  45.    
  46.     aux = Lista;
  47.    
  48.     printf("La Lista contiene los siguientes datos: \n");
  49.    
  50.     while(aux!=NULL){
  51.        
  52.         printf("Edad: /%d Telefono: %d Nombre: %s -> \n", aux->edad, aux->telef, aux->nombre);
  53.         aux = aux->sig;
  54.        
  55.     }
  56.    
  57.     printf("NULL");
  58. }
  59.  
  60. int main(){
  61.    
  62.     miembro *Lista1;
  63.     char *Nombre;
  64.     int age;
  65.     double teleph;
  66.        
  67.     Lista1->edad = 19;
  68.     Lista1->telef = 657485748;
  69.     Lista1->nombre = 'Alfonso';
  70.    
  71.     Lista1->sig = NULL;
  72.    
  73.     printf("Indique el nombre que quiere introducir: ");
  74.     scanf("%s", Nombre);
  75.     printf("\n");
  76.    
  77.     fflush(stdin);
  78.    
  79.     printf("Indique el telefono: ");
  80.     scanf("%d", &teleph);
  81.     printf("\n");
  82.    
  83.     printf("Indique la edad: ");
  84.     scanf("%d", &age);
  85.    
  86.     Lista1 = CrearMiembro(Lista1, teleph, age, Nombre);
  87.    
  88.     ImprimirLista(Lista1);
  89.    
  90.    
  91.    
  92.     system("PAUSE");
  93. }

No da ningún error de compilación, sin embargo, al ejecutarlo deja de funcianar y no sé por qué.
  #2 (permalink)  
Antiguo 25/06/2015, 08:31
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Duda programación en C

Código C:
Ver original
  1. int main()
  2. {
  3.     miembro *Lista1;
  4.  
  5.     // ...        
  6.  
  7.     Lista1->edad = 19;
  8.     Lista1->telef = 657485748;
  9.     Lista1->nombre = 'Alfonso';
  10. }

Lista1 está declarada como puntero... pero no está incializada... es un puntero que apunta a una dirección de memoria aleatoria a la cual muy seguramente no tengas acceso.

Antes de escribir algo en Lista1 hay que inicializarla:

Código C:
Ver original
  1. miembro* Lista1 = (miembro*)malloc(sizeof(miembro));

Y, por supuesto, no has de olvidar que por cada malloc que hagas tienes que añadir un free para liberar la memoria... que estás finalizando el programa sin liberar la memoria que has reservado y eso no está bien visto en ninguna parte.

Un saludo
  #3 (permalink)  
Antiguo 25/06/2015, 08:54
 
Fecha de Ingreso: junio-2015
Mensajes: 4
Antigüedad: 8 años, 10 meses
Puntos: 0
Respuesta: Duda programación en C

Gracias por tu comentario, ahora permite escribir los datos, sin embargo, en la propia ejecución, cuando va a mostrar los datos se "crashea" el programa, dejo el nuevo código:

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4.  
  5. struct Datos{
  6.     char *nombre;
  7.     int edad;
  8.     double telef;
  9.     struct Datos *sig;
  10. };
  11.  
  12. typedef struct Datos miembro;
  13.  
  14. miembro *CrearMiembro(miembro *Lista, double telefono, int anios, char *name){
  15.    
  16.     miembro *NuevoMiembro, *aux;
  17.     NuevoMiembro = (miembro *) malloc(sizeof(miembro));
  18.    
  19.     if(NuevoMiembro != NULL){
  20.         NuevoMiembro->edad = anios;
  21.         NuevoMiembro->telef = telefono;
  22.         NuevoMiembro->nombre = name;
  23.         NuevoMiembro->sig = NULL;
  24.     }
  25.    
  26.         if (Lista == NULL){
  27.             Lista = NuevoMiembro;
  28.         }
  29.         else{
  30.             aux = Lista;
  31.            
  32.             while(aux->sig != NULL){
  33.                 aux = aux->sig;
  34.             }
  35.            
  36.             aux = NuevoMiembro;
  37.         }
  38.    
  39.     return Lista;
  40. }
  41.  
  42. void ImprimirLista(miembro *Lista){
  43.    
  44.     miembro *aux;
  45.    
  46.     aux = Lista;
  47.    
  48.     printf("La Lista contiene los siguientes datos: \n");
  49.    
  50.     while(aux!=NULL){
  51.        
  52.         printf("Edad: /%d Telefono: %d Nombre: %s -> \n", aux->edad, aux->telef, aux->nombre);
  53.         aux = aux->sig;
  54.        
  55.     }
  56.    
  57.     printf("NULL");
  58. }
  59.  
  60. int main(){
  61.    
  62.     miembro* Lista1 = (miembro*)malloc(sizeof(miembro));
  63.    
  64.     char *Nombre;
  65.     int age;
  66.     double teleph;
  67.    
  68.     Lista1 = NULL;
  69.    
  70.     printf("Indique el nombre que quiere introducir: ");
  71.     scanf("%s", &Nombre);
  72.     printf("\n");
  73.    
  74.     fflush(stdin);
  75.    
  76.     printf("Indique el telefono: ");
  77.     scanf("%d", &teleph);
  78.     printf("\n");
  79.    
  80.     printf("Indique la edad: ");
  81.     scanf("%d", &age);
  82.    
  83.     Lista1 = CrearMiembro(Lista1, teleph, age, Nombre);
  84.     ImprimirLista(Lista1);
  85.    
  86.     free(Lista1);
  87.    
  88.    
  89.     system("PAUSE");
  90. }
  #4 (permalink)  
Antiguo 25/06/2015, 09:16
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Duda programación en C

Te estás haciendo un lío con los punteros:

Si haces:

Lista1 = malloc()

y después haces

Lista1 = CrearMiembro

¿qué sucede con la primera reserva de memoria? se pierde, dejando por el camino lo que se llaman fugas de memoria. El efecto de estas fugas de memoria es que la máquina cada vez va a tener menos memoria disponible, ya que no se libera, hasta que llega un punto en el que se le agota la memoria libre y algo acaba cascando.

Es decir, si llamas a CrearMiembro (que en tu primera versión no lo hacías hasta después de intentar acceder a los miembros de Lista1) no necesitas hacer malloc.

Además, en el main sigues teniendo punteros sin inicializar:
Código C:
Ver original
  1. char *Nombre;
  2.  
  3. // ...    
  4.  
  5. printf("Indique el nombre que quiere introducir: ");
  6. scanf("%s", &Nombre);
  7. printf("\n");

¿Dónde está la memoria reservada para almacenar la cadena de Nombre? En ningún sitio.

Puedes optar por calcular un tamaño lo suficientemente grande como para que entre cualquier nombre y evitar el uso de memoria dinámica:

Código C:
Ver original
  1. char Nombre[100];

Por otro lado, si analizamos la función CrearMiembro:

Código C:
Ver original
  1. miembro *CrearMiembro(miembro *Lista, double telefono, int anios, char *name)
  2. {
  3.     miembro *NuevoMiembro, *aux;
  4.     NuevoMiembro = (miembro *) malloc(sizeof(miembro));
  5.    
  6.     if(NuevoMiembro != NULL){
  7.         NuevoMiembro->edad = anios;
  8.         NuevoMiembro->telef = telefono;
  9.         NuevoMiembro->nombre = name; // <<--- 1
  10.         NuevoMiembro->sig = NULL;
  11.     }
  12.    
  13.     if (Lista == NULL){
  14.         Lista = NuevoMiembro;
  15.     }
  16.     else
  17.     {
  18.         aux = Lista;
  19.            
  20.         while(aux->sig != NULL){
  21.             aux = aux->sig;
  22.         }
  23.            
  24.         aux = NuevoMiembro; // <<--- 2
  25.     }
  26.    
  27.     return Lista;
  28. }

1. Las cadenas de texto no se pueden copiar así... o bien declaras nombre como un array de tamaño fijo o bien haces una reserva dinámica de memoria para que entre la cadena que quieres copiar y, a continuación, tienes que usar strcmp para copiar una cadena en otra. Si haces una copia de punteros tienes que ser consciente de que la dirección de memoria apuntada es compartida y tienes que manejarla con cuidado.

2. ¿Aquí no tendría que ser aux->sig = NuevoMiembro?

Y, bueno, ya puestos, lo mejor sería que empezases a trastear con el depurador de código. Es una herramienta imprescindible en este mundillo y es mejor aprender a usarla con programas pequeños.

Un saludo

Etiquetas: char, int, struct
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:44.