Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: soyloqbuskas en 3 Noviembre 2012, 06:03 am



Título: time() localtime()
Publicado por: soyloqbuskas en 3 Noviembre 2012, 06:03 am
Buenas a todos!

tengo un problema con esta funcion...me da fallo de segmentacion en la funcion localtime()
Código
  1. char * getDateTime(){
  2.        char * fecha=(char*)malloc(200);
  3.        time_t t = time(NULL);
  4.        struct tm *tm = localtime(&t);
  5.        char * dia="";
  6.        char * mes="";
  7.  
  8.        switch(tm->tm_wday){
  9.  
  10.                case 0: dia="Sun"; break;
  11.                case 1: dia="Mon"; break;
  12.                case 2: dia="Tue"; break;
  13.                case 3: dia="Wed"; break;
  14.                case 4: dia="Thu"; break;
  15.                case 5: dia="Fri"; break;
  16.                case 6: dia="Sat"; break;
  17.                default: dia="???"; break;
  18.        }
  19.  
  20.        switch(tm->tm_mon){
  21.  
  22.                case 0: mes="Jan"; break;
  23.                case 1: mes="Feb"; break;
  24.                case 2: mes="Mar"; break;
  25.                case 3: mes="Apr"; break;
  26.                case 4: mes="May"; break;
  27.                case 5: mes="Jun"; break;
  28.                case 6: mes="Jul"; break;
  29.                case 7: mes="Aug"; break;
  30.                case 8: mes="Sep"; break;
  31.                case 9: mes="Oct"; break;
  32.                case 10: mes="Nov"; break;
  33.                case 11: mes="Dec"; break;
  34.                default: mes="???"; break;
  35.        }
  36.  
  37.        sprintf(fecha,"Date: %s , %d %s %d %d:%d:%d GMT",dia, tm->tm_mday, mes, tm->tm_year+1900, tm->tm_hour, tm->tm_min, tm->tm_sec);
  38.        return fecha;
  39. }
  40.  

¿Por que me da fallo de segmentacion?

Gracias, un saludo


Título: Re: time() localtime()
Publicado por: ecfisa en 3 Noviembre 2012, 07:52 am
Hola soyloqbuskas.

No sé con que compilador estes trabajando, pero probé tu código en CodeBlocks (GNU GCC Compiler) y en Builder C++ 6 y en ambos funciona sin provocar error alguno. Pero de ese modo se te presenta el problema de como liberar la memoria asignada con malloc a la variable local fecha.

Quizá sería mejor:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. void getDateTime(char **fecha) {
  6.  time_t t = time(NULL);
  7.  struct tm *tm = localtime(&t);
  8.  char *dia = "";
  9.  char *mes = "";
  10.  
  11.  switch(tm->tm_wday){
  12.    case 0: dia="Sun"; break;
  13.    case 1: dia="Mon"; break;
  14.    case 2: dia="Tue"; break;
  15.    case 3: dia="Wed"; break;
  16.    case 4: dia="Thu"; break;
  17.    case 5: dia="Fri"; break;
  18.    case 6: dia="Sat"; break;
  19.    default: dia="???"; break;
  20.  }
  21.  
  22.  switch(tm->tm_mon){
  23.    case 0: mes="Jan"; break;
  24.    case 1: mes="Feb"; break;
  25.    case 2: mes="Mar"; break;
  26.    case 3: mes="Apr"; break;
  27.    case 4: mes="May"; break;
  28.    case 5: mes="Jun"; break;
  29.    case 6: mes="Jul"; break;
  30.    case 7: mes="Aug"; break;
  31.    case 8: mes="Sep"; break;
  32.    case 9: mes="Oct"; break;
  33.    case 10: mes="Nov"; break;
  34.    case 11: mes="Dec"; break;
  35.    default: mes="???"; break;
  36.  }
  37.  sprintf(*fecha,"Date: %s , %d %s %d %d:%d:%d GMT",dia, tm->tm_mday, mes, tm->tm_year+1900, tm->tm_hour, tm->tm_min, tm->tm_sec);
  38. }
  39.  
  40. int main() {
  41.  char *fecha=(char*)malloc(200);
  42.  
  43.  getDateTime(&fecha);
  44.  printf("%s", fecha);
  45.  
  46.  free(fecha);
  47.  ...
  48. }
  49.  

Saludos.


Título: Re: time() localtime()
Publicado por: BatchianoISpyxolo en 3 Noviembre 2012, 13:17 pm
Sep, En CodeBlocks con el GCC funciona aunque hay que liberar la memoria de fecha xD

Compilando con gcc desde consola te debería de ir igual :]


Título: Re: time() localtime()
Publicado por: Khronos14 en 3 Noviembre 2012, 13:50 pm
Te da fallo de segmentación por los punteros dia y mes. Los inicias a vacío y luego modificas su tamaño, sobreescribiendo datos de la pila que pueden afectar a otras variables. Falle a veces porque depende los datos que haya en la pila y si llega a afectar al segmento de datos es cuando rompe el programa.

La solución es declarar un array de 4 caracteres y no te complicas. Otra cosa: no te olvides de hacer un free después de llamar a getDateTime, porque produce un Memory Leak.

Saludos.


Título: Re: time() localtime()
Publicado por: rir3760 en 3 Noviembre 2012, 16:55 pm
Te da fallo de segmentación por los punteros dia y mes. Los inicias a vacío y luego modificas su tamaño, sobreescribiendo datos de la pila que pueden afectar a otras variables.
No hay problema en la forma en que soyloqbuskas utiliza los punteros "mes" y "dia":
Código
  1. char *dia = "";
  2.  
  3. /* ... */
  4.  
  5. case 0:
  6.   dia = "Sun";
  7.   break;
  8. case 1:
  9.   dia = "Mon";
  10.   break;
Ya que en cada una de esas asignaciones solo almacena en la variable "dia" una nueva dirección de memoria: la dirección donde se almacena la cadena literal.


En cuanto a la función para formatear la fecha no es necesario hacerlo manualmente, en su lugar se puede utilizar la función strftime (http://www.cplusplus.com/reference/clibrary/ctime/strftime/) (prototipo en <time.h>), por ejemplo (sin validación de errores):
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. char *getDateTime(void);
  6.  
  7. int main (void)
  8. {
  9.   char *fecha;
  10.  
  11.   fecha = getDateTime();
  12.   printf("%s\n", fecha);
  13.   free(fecha);
  14.  
  15.   return EXIT_SUCCESS;
  16. }
  17.  
  18. char *getDateTime(void)
  19. {
  20.   char *cad = malloc(1024);
  21.   time_t t = time(NULL);
  22.   struct tm *tm = localtime(&t);
  23.   size_t nc;
  24.  
  25.   nc = strftime(cad, 1024, "Date: %a, %d %b %Y %H:%M:%S %Z", tm);
  26.   cad = realloc(cad, nc + 1);
  27.  
  28.   return cad;
  29. }

Un saludo