Error de segmentacion trabajando con listas

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

Error de segmentacion trabajando con listas

Notapor lacabra25 » Dom Ene 11, 2009 6:26 pm

Hola, tengo un programa en el que trabajo con listas y el problema me surje al intentar hacer que el puntero adentro de la estructura apunte al siguiente elemento o a si mismo en caso de ser el unico elemento, lo he estado mirando con el debuger y os paso el resultado:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004011ee in cargar_participantes (ruta_archivo=0x402386 "campeonato.xml") at archivos.c:169
169 lista_categorias->siguiente= lista_categorias;


No entiendo por que me da un error de fragmentacion.

Os dejo el codigo de la funcion donde da el error:
Código: Seleccionar todo
int cargar_participantes(char *ruta_archivo){
   enum estado {espera, fin_campeonato, leyendo_campeonato, leyendo_participante, leyendo_categoria} estado=espera;
   register int r=0, f1=0, f2=0;
   char cl[101];
   participante *participantes, *p_temporal;
   categoria *categorias, *c_temporal, *c_auxiliar;
   if(ruta_archivo != NULL){
      FILE *archivo;
      archivo= fopen(ruta_archivo, "r");
      if(archivo != NULL){
         while(fscanf(archivo, "%s", &cl[0]) != EOF){
            if(strcmp(&cl[0], "<championship>") == 0){
               if(estado == espera){
                  estado= leyendo_campeonato;
               }else{
                  r=3;
                  break;
               }
            }else if(strcmp(&cl[0], "<title>") == 0){
               while(strcmp(&cl[0], "</title>") != 0 && fscanf(archivo, "%s", &cl[0]) != EOF){
                  if(strcmp(&cl[0], "</title>") == 0){
                     f1=0;
                     break;
                  }else{
                     switch(estado){
                        case leyendo_campeonato: if(f1 == 0){
                              strcpy(&titulo_campeonato[0], &cl[0]);
Código: Seleccionar todo
                              f1=1;

                           }else{
                              if((strlen(&titulo_campeonato[0]) + strlen(&cl[0])) < 100){
                                 strcat(&titulo_campeonato[0], " ");
                                 strcat(&titulo_campeonato[0], &cl[0]);
                              }
                           }
                           break;
                        case leyendo_categoria: c_temporal= &(p_temporal->categorias[f2]);
                              if(f1 == 0){
                              /*incorporando la categoria a las categorias en las que participa el participante*/
                              strcpy(&c_temporal->nombre[0], &cl[0]);
                              f1=1;
                           }else{
                              if((strlen(&c_temporal->nombre[0]) + strlen(&cl[0])) < 100){
                                 strcat(&c_temporal->nombre[0], " ");
Código: Seleccionar todo
                                 strcat(&c_temporal->nombre[0], &cl[0]);
                              }
                           }
                           break;
                        case leyendo_participante: break;
                        default: break;
                     }
                  }
               }
            }else if(strcmp(&cl[0], "<participant>") == 0){
               if(estado == leyendo_campeonato){
                  /*reservando memoria para el nuevo participante*/
                  p_temporal=(participante *) malloc(sizeof(participante));
                  estado= leyendo_participante;
                  f2=0;
               }else{
                  r=3;
                  break;
               }
            }else if(strcmp(&cl[0], "<name>") == 0){
               while(strcmp(&cl[0], "</name>") != 0 && fscanf(archivo, "%s", &cl[0]) != EOF){
                  if(strcmp(&cl[0], "</name>") == 0){
                     f1=0;
                     break;
Código: Seleccionar todo
                  }else{
                     switch(estado){
                        case leyendo_participante: if(f1 == 0){
                              /*copiando la cadena en su correspondiente lugar en la estructura del nuevo participante*/
                              strcpy(&p_temporal->nombre[0], &cl[0]);
                              f1=1;
                           }else{
                              /*concatenando la cadena del nombre que falta al nombre dejando un espacio por medio si hay espacio en la cadena de la estructura*/
                              if((strlen(&p_temporal->nombre[0]) + strlen(&cl[0])) < 100){
                                 strcat(&p_temporal->nombre[0], " ");
                                 strcat(&p_temporal->nombre[0], &cl[0]);
                              }
                           }
                           break;
                        default: break;
                     }
                  }
               }
            }else if(strcmp(&cl[0], "</participant>") == 0){
               if(estado == leyendo_participante){
                  /*copiando la categoria*/
Código: Seleccionar todo
                  c_auxiliar= (categoria *) malloc(sizeof(categoria));
                  strcpy(&c_auxiliar->nombre[0], &c_temporal->nombre[0]);
                  c_temporal= c_auxiliar;
                  /*añadiendo el nuevo participante a la lista de participantes*/
                  if(participantes == NULL){
                     participantes= p_temporal;
                     participantes->siguiente= participantes;
                     participantes->anterior= participantes;
                  }else{
                     p_temporal->siguiente= participantes->siguiente;
                     p_temporal->anterior= participantes;
                     participantes->siguiente->anterior= p_temporal;
Código: Seleccionar todo
                     participantes->siguiente= p_temporal;
                     participantes= participantes->siguiente;
                  }
                  estado= leyendo_campeonato;
               }else{
                  r=3;
                  break;
               }
            }else if(strcmp(&cl[0], "<result>") == 0){
               if(estado == leyendo_categoria){
                  c_temporal= &(p_temporal->categorias[f2]);
                  fscanf(archivo, "%f", &(c_temporal->puntuacion));
               }else{
                  r=3;
                  break;
               }
Código: Seleccionar todo
            }else if(strcmp(&cl[0], "</result>") == 0){
               if(estado == leyendo_categoria){
                  estado= leyendo_categoria;
               }else{
                  r=3;
                  break;
               }
            }else if(strcmp(&cl[0], "<category>") == 0){
               if(estado == leyendo_participante){
                  estado= leyendo_categoria;
               }else{
                  r=3;
                  break;
               }
Código: Seleccionar todo
            }else if(strcmp(&cl[0], "</category>") == 0){
               if(estado == leyendo_categoria){
                  /*actualizando la lista de categorias en la variable global*/
                  if(lista_categorias == NULL){
                     categorias->siguiente= categorias;
                     categorias->anterior= categorias;
                  }
                  lista_categorias= categorias;
                  /*comprobando si la categoria incluida entre categorias del participante esta en la lista total de categorias y en caso negativo añadiendola*/
                  if(existe_categoria(c_temporal) == 0){
                     if(categorias == NULL){
                        categorias= c_temporal;
                        categorias->siguiente= c_temporal;
                        categorias->anterior= c_temporal;
                     }else{
                        c_temporal->siguiente= categorias->siguiente;
                        c_temporal->anterior= categorias;
Código: Seleccionar todo
                        categorias->siguiente->anterior= c_temporal;
                        categorias->siguiente= c_temporal;
                        categorias= categorias->siguiente;
                     }
                  }
                  estado= leyendo_participante;
                  f2++;
               }else{
                  r=3;
                  break;
               }
            }
         }
         fclose(archivo);
      }else{
         r=2;
         printf("Error abriendo archivo %s\n", ruta_archivo);
      }
   }else{
      r=1;
   }
   /*devolviendo las listas de participantes y categorias totales*/
   lista_participantes= participantes->siguiente;
   lista_categorias= categorias;
   return r;
}


Lo pego en varios cachos para que no se corte.[/code]
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor hugoruscitti » Dom Ene 11, 2009 8:12 pm

ummm... siquiera pude compilarlo porque faltan algunos
datos... De todas formas, cuando trabajes con C, es muy
recomendable que utilices un depurador como gdb, o
incluso un versión gráfica como DDD. Estos programas
te permiten ejecutar tu proyecto paso a paso, ver las
estructuras de memoria mientras tu programa se está
ejecutando e incluso saber la linea exacta donde falla (en
caso de recibir un Segmentation Fault).

El depurador se ve algo así:

Imagen

Prueba leyendo estos otros mensajes del foro, seguramente te
resulte mucho mas sencillo encontrar el error usando estas
herramientas:

- http://www.losersjuegos.com.ar/foro/viewtopic.php?t=318
- http://www.losersjuegos.com.ar/foro/viewtopic.php?t=162

Saludos.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Notapor lacabra25 » Dom Ene 11, 2009 10:33 pm

dbg es lo que utilice para saber la parte que falla, pero no entiendo el por que falla por que no deberia, dbg devolvio esto:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004011ee in cargar_participantes (ruta_archivo=0x402386 "campeonato.xml") at archivos.c:169
169 lista_categorias->siguiente= lista_categorias;

Falla la linea:
lista_categorias->siguiente= lista_categorias;

Pero no entiendo el por que, simplemente hago que el puntero al siguiente elemento apunte a si mismo.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor hugoruscitti » Lun Ene 12, 2009 3:36 am

lacabra25 escribió:Falla la linea:
lista_categorias->siguiente= lista_categorias;

Pero no entiendo el por que, simplemente hago que el puntero al siguiente elemento apunte a si mismo.


Pero depende del contexto, digo, que tal si "lista_categoria"
apunta a una dirección incorrecta de memoria. La simple
asignación en el registro "siguiente" puede ocacionar la falla. Intenta
usar DDD, cuando el programa falle consulta el valor de la variable
"lista_categoria". Generalmente los problemas de memoria se
ocasionan algunas sentencias antes, es recomendable hacer
un seguimiento paso a paso a partir de un breakpoint cercano a
la linea 169.

Saludos.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Notapor lacabra25 » Jue Ene 15, 2009 4:42 pm

Una cosa que me estraña es que si en la ultima linea de la fucion main, antes de return, pongo exit(0) el programa se ejecuta perfecto sin dar fallo.

De todos modos voy a hacer una funcion que se encargue de crear los miembros de la lista y de meterlos en la lista copiando el contenido que se pase como argumento al contenido de la estructura del elemento, de ese modo espero que no de fallo.

Tambien he pensado que puede que de fallo por como intento hacer una lista con elementos que estan en un array dentro de otra estructura, por eso pense lo de la funcion que se encargue de copiar el contenido a un nuevo elemento y meterlo en la lista.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor hugoruscitti » Jue Ene 15, 2009 8:27 pm

lacabra25 escribió:Una cosa que me estraña es que si en la ultima linea de la fucion main, antes de return, pongo exit(0) el programa se ejecuta perfecto sin dar fallo.


Si, resulta que el sistema operativo es quien detecta el fallo
y aborta el programa. En muchos casos este instante, el de
interrupción, es diferente o impreciso. De todas formas es
común, generalmente se da cuando el sistema operativo
hace una operación de IO, como leer un archivo o imprimir. Algo
desconcertante realmente...
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron