Error de violación de segmento ('core' generado) en C

Moderadores: Kravenbcn, largeroliker, fidelcastro, cerealkiller, pspCaracas, m0skit0, LnD, ka69, zacky06

Responder
Avatar de Usuario
driKton
Moderador
Moderador
Mensajes: 1099
Registrado: 04 Sep 2009, 14:30
PSN ID: DarkCarlx10
Steam ID: drikton
Twitter: driKton
Ubicación: Santa Cruz de Tenerife
Contactar:

Error de violación de segmento ('core' generado) en C

Mensaje por driKton »

Tengo un problemilla con una práctica que andamos haciendo en la universidad, a ver si me podéis echar una mano :lol:

Este es el enunciado del ejercicio:
Spoiler:
Universidad escribió:2.- Escribir un programa que trabaja con fechas de nacimiento de personas. Para guardar cada fecha se utilizará una estructura donde los tres campos, día, mes y año se declaran como enteros o enteros sin signo. Para guardar los datos de las personas se usa un vector del tipo anterior. La definición del tipo se hace global, pero la declaración del vector se hace en la función main. El número de fechas a leer se pide en la función main. La lectura de cada fecha se hace en una función. La escritura en pantalla de una fecha se hace también en una función, indicando el mes como una cadena de caracteres, (como ayuda, se supone que está
declarado a nivel global el siguiente vector de cadenas de caracteres).

#define SIZEMESES 11
#define NMESES 12

char meses[NMESES][SIZEMESES] = {"enero", "febrero", "marzo", “abril”, “mayo”,
“junio”, “julio”, “agosto”, “septiembre”, “octubre”, “noviembre”, “diciembre”};

Implementar una función para calcular las fechas de nacimiento menor y mayor, que serán
calculadas por la función como índices del vector de fechas. Dicha función devolverá los índices
mediante una struct.


Este es el código que tengo ahora mismo:
Spoiler:

Código: Seleccionar todo

#include <stdio.h>
#define SIZEMESES 11
#define NMESES 12
#define MAX 10

char meses[NMESES][SIZEMESES] = {"enero", "febrero", "marzo", "abril", "mayo", "junio", "julio",
                                 "agosto", "septiembre", "octrubre", "noviembre", "diciembre"};

//Estructura para almacenar las fechas
typedef struct{

  int day;
  int month;
  int year;

}Tfecha;

//Estructura para almacenar los índices
typedef struct{
 
  int mayor;
  int menor;
 
}Tindicador;

//Función para leer las fechas
int leerfecha(int i, Tfecha personas[]){
 
  printf("Introduzca el dia: ");
  scanf("%d" , &personas[i].day);
  printf("Introduzca el mes: ");
  scanf("%d" , &personas[i].month);
  printf("Introduzca el año: ");
  scanf("%d" , &personas[i].year);
  printf("--------------------------------\n");
 
}

//Mostrar por pantalla las fechas
int printfecha(int i, Tfecha personas[]){
 
   personas[i].month -= 1;
   printf("---Persona %d---\n",i+1);
        printf("%d de %s de %d\n",personas[i].day,meses[personas[i].month],personas[i].year);
}


//Función para comparar las fechas
Tindicador compfechas(Tfecha personas[], int num){

Tindicador indicadores; 
int i;
int highyear, highmonth, highday, lessyear, lessmonth, lessday;
 
  //La fechas mayor y menor debe ser, como mínimo, las almacenada en personas[0]
  highyear = personas[0].year;
  highmonth = personas[0].month;
  highday = personas[0].day;
 
  lessyear = personas[0].year;
  lessmonth = personas[0].month;
  lessday = personas[0].day;
 
    for(i=1 ; i < num ; i++){
     
     /* -INICIO COMPARACION FECHA MAYOR */
    
      if(highyear < personas[i].year){               /*Si el año es mayor a 'highyear' cambiamos el valor de 'highyear'
                                          y guardamos la posición*/
         highyear = personas[i].year;
         highmonth = personas[i].month;
         highday = personas[i].day;
   
         indicadores.mayor = i;
      
      } else if(highyear == personas[i].year){          //Si el año es igual, comparamos los meses
   
            if (highmonth < personas[i].month){       /*Si el mes es mayor a 'highmonth', modificamos 'highyear', 'highmonth' y 'highday'
                                             y guardamos la posicion*/
               highyear = personas[i].year;
               highmonth = personas[i].month;
               highday = personas[i].day;
    
               indicadores.mayor = i;
         
            } else if (highmonth == personas[i].month){         //Si el mes es igual a 'highmonth', comparamos el día
    
                  if (highday > personas[i].day){            /*Si el dia es menor a 'highday', modificamos 'highyear', 'highmonth' y 'highday'
                                                   y guardamos la posicion*/
                     highyear = personas[i].year;
                     highmonth = personas[i].month;
                     highday = personas[i].day;
                  
                     indicadores.mayor = i;
                  }
               }
         }
   
     
     /* -FINAL COMPARACION FECHA MAYOR */
     
     /* -INICIO COMPARACION FECHA MENOR */
    
     if(lessyear > personas[i].year){               /*Si el año es menor a 'lessyear' cambiamos el valor de 'lessyear'
                                          y guardamos la posición*/
         lessyear = personas[i].year;
         lessmonth = personas[i].month;
         lessday = personas[i].day;
   
         indicadores.menor = i;
      
      }else if(lessyear == personas[i].year){         //Si son iguales, comparamos meses
   
            if (lessmonth > personas[i].month){      //Si es menor, modificamos las variables y guardamos posición
    
               lessyear = personas[i].year;
               lessmonth = personas[i].month;
               lessday = personas[i].day;
    
               indicadores.menor = i;
            }else if (lessmonth == personas[i].month){      //Si son iguales, comparamos día
    
                  if (lessday < personas[i].day){         //Si es menor, modificamos las variables y guardamos posición
      
                     lessyear = personas[i].year;
                     lessmonth = personas[i].month;
                     lessday = personas[i].day;
    
                     indicadores.menor = i;
                  }
               }
         }
    }
   
   /* -FINAL COMPARACION FECHA MENOR */
   
    return(indicadores);  //Devolvemos los indicadores como un struct

 

int main (void){

int i;
int num;
Tfecha personas[MAX];
Tindicador indicadores;
 
  //Pedimos el número de fechas
  printf("--------------****----------------\n");
  printf("¿Cuantas fechas desea introducir?:");
  scanf ("%d" , &num);
  printf("--------------****----------------\n");
 
  //Leemos las fechas llamando a la función leerfecha()
  for(i = 0; i < num; i++){
    leerfecha(i, personas);
  }
 
  //Mostramos por pantalla llamando a la función printfecha()
  printf("Las fechas introducidas son:\n");
 
  for(i = 0; i < num; i++){
   printfecha(i, personas);   
  }
 
  //Llamamos a la funcion compfecha() y mostramos la fecha mayor y menor
  indicadores = compfechas(personas, num);
 
  printf("--------------****----------------\n");
  printf("La fecha menor es %d de %s de %d\n", personas[indicadores.menor].day, meses[personas[indicadores.menor].month], personas[indicadores.menor].year);
  printf("La fecha mayor es %d de %s de %d\n", personas[indicadores.mayor].day, meses[personas[indicadores.mayor].month], personas[indicadores.mayor].year);
  printf("--------------****----------------\n");
 
}

También os dejo un Pastebin por si preferís los colorines :lol: Enlace

Al meter 4 fechas, funciona bien (creo), si meto menos o más de 4, me salta violación de segmento ('core' generado)

P.D No tenía el código comentado ni indentado...así que es posible que haya aparecido algún error de sintaxis por estar toqueteando (no puedo probar a compilarlo de nuevo ahora mismo) xDD Cualquier cosa me decís ;)

Saludos!
Última edición por driKton el 11 Dic 2013, 19:40, editado 3 veces en total.
Imagen

Avatar de Usuario
largeroliker
Administrador
Administrador
Mensajes: 8283
Registrado: 03 Sep 2009, 09:46
PSN ID: larger0o
Gamertag Xbox Live: larger0o
Steam ID: larger0o
Twitter: larger0o
Ubicación: Málaga
Contactar:

Re: Error de violación de segmento ('core' generado) en C

Mensaje por largeroliker »

Estoy quizás un poco pez en C, pero:

char meses[NMESES][SIZEMESES] = {"enero", "febrero", "marzo", “abril”, “mayo”,
“junio”, “julio”, “agosto”, “septiembre”, “octubre”, “noviembre”, “diciembre”};

Eso no genera un array bidimensional de tamaño SIZEMESES en la posición NMESES de la dimensión 0 pero de char!?

Porque le estás metiendo strings.
Imagen
Steam Deck · Xbox Series X · PS5 · Switch · PS Vita · WiiU · PS3 · new 3DS XL · Xbox 360 · PSP · PS2

Avatar de Usuario
driKton
Moderador
Moderador
Mensajes: 1099
Registrado: 04 Sep 2009, 14:30
PSN ID: DarkCarlx10
Steam ID: drikton
Twitter: driKton
Ubicación: Santa Cruz de Tenerife
Contactar:

Re: Error de violación de segmento ('core' generado) en C

Mensaje por driKton »

largeroliker escribió:Estoy quizás un poco pez en C, pero:

char meses[NMESES][SIZEMESES] = {"enero", "febrero", "marzo", “abril”, “mayo”,
“junio”, “julio”, “agosto”, “septiembre”, “octubre”, “noviembre”, “diciembre”};

Eso no genera un array bidimensional de tamaño SIZEMESES en la posición NMESES de la dimensión 0 pero de char!?

Porque le estás metiendo strings.

Justo esa parte del código no es mía (viene en el enunciado para que la añadamos XD)

Ahora mismo no te podría decir con exactitud, pero creo recordar que efectivamente se genera lo que dices, pero se almacena cada letra en una posición.

En el caso de enero, meses[1][1] seria 'e' e indicando únicamente el valor de NMESES obtenemos el mes como string (en el caso en el que el programa funciona, introduciendo 4 fechas, se muestra bien sin dar ningún error)
Imagen

Avatar de Usuario
largeroliker
Administrador
Administrador
Mensajes: 8283
Registrado: 03 Sep 2009, 09:46
PSN ID: larger0o
Gamertag Xbox Live: larger0o
Steam ID: larger0o
Twitter: larger0o
Ubicación: Málaga
Contactar:

Re: Error de violación de segmento ('core' generado) en C

Mensaje por largeroliker »

Ah, pues de eso no tenía ni idea. Ni sé si se puede hacer con C# que es con lo que estoy ahora :lol:

Reviso el resto del código a ver si veo algo.
Imagen
Steam Deck · Xbox Series X · PS5 · Switch · PS Vita · WiiU · PS3 · new 3DS XL · Xbox 360 · PSP · PS2

Avatar de Usuario
largeroliker
Administrador
Administrador
Mensajes: 8283
Registrado: 03 Sep 2009, 09:46
PSN ID: larger0o
Gamertag Xbox Live: larger0o
Steam ID: larger0o
Twitter: larger0o
Ubicación: Málaga
Contactar:

Re: Error de violación de segmento ('core' generado) en C

Mensaje por largeroliker »

Veo un fallito en leerfecha()

En la firma del método estás diciendo que debe aceptar dos variables, un entero i y un array de estructura personas[]. Sin embargo, cuando lo llamas en el main le pasas 3 parámetros: i, num y personas.

Lo que yo no sé es cómo eso no revienta :lol:
Imagen
Steam Deck · Xbox Series X · PS5 · Switch · PS Vita · WiiU · PS3 · new 3DS XL · Xbox 360 · PSP · PS2

Avatar de Usuario
driKton
Moderador
Moderador
Mensajes: 1099
Registrado: 04 Sep 2009, 14:30
PSN ID: DarkCarlx10
Steam ID: drikton
Twitter: driKton
Ubicación: Santa Cruz de Tenerife
Contactar:

Re: Error de violación de segmento ('core' generado) en C

Mensaje por driKton »

largeroliker escribió:Veo un fallito en leerfecha()

En la firma del método estás diciendo que debe aceptar dos variables, un entero i y un array de estructura personas[]. Sin embargo, cuando lo llamas en el main le pasas 3 parámetros: i, num y personas.

Lo que yo no sé es cómo eso no revienta :lol:

Cierto, se me ha colado de una "versión" anterior en la que si pasaba num :lol: Si te fijas en printfecha() pasaba lo mismo :)

Corregido eso! :oki:
Imagen

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Error de violación de segmento ('core' generado) en C

Mensaje por m0skit0 »

El array de meses está bien declarado. El primer valor es el número de meses, el segundo el tamaño máximo de mes. De todas formas es una sintaxis bastante extraña, innecesaria y que reserva memoria que nunca se va a usar. Puedes hacer simplemente:

Código: Seleccionar todo

char* meses[NUM_MESES] = {los asignas igual};

El resto ahora lo miro, me voy a papear!
Imagen

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Error de violación de segmento ('core' generado) en C

Mensaje por m0skit0 »

En cuanto a usar scanf, te aconsejo que te leas este artículo (está en inglés, como todo lo bueno en internet...).
Imagen

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Error de violación de segmento ('core' generado) en C

Mensaje por m0skit0 »

Y yendo al tema, ¿dónde ocurre la violación de segmento? Usa un depurador (pej GDB) para ir paso a paso y ver qué está pasando.
Imagen

Avatar de Usuario
driKton
Moderador
Moderador
Mensajes: 1099
Registrado: 04 Sep 2009, 14:30
PSN ID: DarkCarlx10
Steam ID: drikton
Twitter: driKton
Ubicación: Santa Cruz de Tenerife
Contactar:

Re: Error de violación de segmento ('core' generado) en C

Mensaje por driKton »

Perdón por tardar tanto en contestar, entre prácticas y los exámenes de Enero estamos hasta arriba xDD Voy por partes.

m0skit0 escribió:El array de meses está bien declarado. El primer valor es el número de meses, el segundo el tamaño máximo de mes. De todas formas es una sintaxis bastante extraña, innecesaria y que reserva memoria que nunca se va a usar. Puedes hacer simplemente:

Código: Seleccionar todo

char* meses[NUM_MESES] = {los asignas igual};

El resto ahora lo miro, me voy a papear!


El tema es que no hemos dado punteros y nos obligan mientras a declararlos así hasta el 2º cuatrimestre que los demos, apuntado queda de todas formas! :)

m0skit0 escribió:En cuanto a usar scanf, te aconsejo que te leas este artículo (está en inglés, como todo lo bueno en internet...).


Como en el caso anterior, únicamente nos dejan utilizar lo que hemos dado (una tontería por otro lado, limitar de esa forma a los alumnos), me lo guardo en favoritos para cuando nos dejen más libertad o me meta a hacer algo por mi cuenta ;)

m0skit0 escribió:Y yendo al tema, ¿dónde ocurre la violación de segmento? Usa un depurador (pej GDB) para ir paso a paso y ver qué está pasando.

Ya está solucionado el tema, usamos el GDB como me recomendaste y en un momento lo solucionamos :P Por si alguien tiene curiosidad, la violación de segmento se producía por no inicializar a 0 indicadores.mayor e indicadores.menor ;)

Gracias por la ayuda jefes :lol:
Imagen

Responder