time() localtime()

Iniciado por soyloqbuskas, 3 Noviembre 2012, 06:03 AM

0 Miembros y 1 Visitante están viendo este tema.

soyloqbuskas

Buenas a todos!

tengo un problema con esta funcion...me da fallo de segmentacion en la funcion localtime()
char * getDateTime(){
        char * fecha=(char*)malloc(200);
        time_t t = time(NULL);
        struct tm *tm = localtime(&t);
        char * dia="";
        char * mes="";
       
        switch(tm->tm_wday){

                case 0: dia="Sun"; break;
                case 1: dia="Mon"; break;
                case 2: dia="Tue"; break;
                case 3: dia="Wed"; break;
                case 4: dia="Thu"; break;
                case 5: dia="Fri"; break;
                case 6: dia="Sat"; break;
                default: dia="???"; break;
        }

        switch(tm->tm_mon){

                case 0: mes="Jan"; break;
                case 1: mes="Feb"; break;
                case 2: mes="Mar"; break;
                case 3: mes="Apr"; break;
                case 4: mes="May"; break;
                case 5: mes="Jun"; break;
                case 6: mes="Jul"; break;
                case 7: mes="Aug"; break;
                case 8: mes="Sep"; break;
                case 9: mes="Oct"; break;
                case 10: mes="Nov"; break;
                case 11: mes="Dec"; break;
                default: mes="???"; break;
        }

        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);
        return fecha;
}


¿Por que me da fallo de segmentacion?

Gracias, un saludo
"Si tienes 1 manzana y yo tengo otra manzana...
y las intercambiamos, ambos seguiremos teniendo 1 manzana.
Pero...si tu tienes 1 idea y yo tengo otra idea...
y las intercambiamos, ambos tendremos 2 ideas."


George Bernard Shaw

ecfisa

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:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void getDateTime(char **fecha) {
  time_t t = time(NULL);
  struct tm *tm = localtime(&t);
  char *dia = "";
  char *mes = "";

  switch(tm->tm_wday){
    case 0: dia="Sun"; break;
    case 1: dia="Mon"; break;
    case 2: dia="Tue"; break;
    case 3: dia="Wed"; break;
    case 4: dia="Thu"; break;
    case 5: dia="Fri"; break;
    case 6: dia="Sat"; break;
    default: dia="???"; break;
  }

  switch(tm->tm_mon){
    case 0: mes="Jan"; break;
    case 1: mes="Feb"; break;
    case 2: mes="Mar"; break;
    case 3: mes="Apr"; break;
    case 4: mes="May"; break;
    case 5: mes="Jun"; break;
    case 6: mes="Jul"; break;
    case 7: mes="Aug"; break;
    case 8: mes="Sep"; break;
    case 9: mes="Oct"; break;
    case 10: mes="Nov"; break;
    case 11: mes="Dec"; break;
    default: mes="???"; break;
  }
  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);
}

int main() {
  char *fecha=(char*)malloc(200);

  getDateTime(&fecha);
  printf("%s", fecha);

  free(fecha);
  ...
}


Saludos.

BatchianoISpyxolo

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 :]
Puede que desees aprender a programar desde 0: www.espascal.es

Khronos14

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.

rir3760

Cita de: 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.
No hay problema en la forma en que soyloqbuskas utiliza los punteros "mes" y "dia":
char *dia = "";

/* ... */

case 0:
   dia = "Sun";
   break;
case 1:
   dia = "Mon";
   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 (prototipo en <time.h>), por ejemplo (sin validación de errores):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

char *getDateTime(void);

int main (void)
{
   char *fecha;
   
   fecha = getDateTime();
   printf("%s\n", fecha);
   free(fecha);
   
   return EXIT_SUCCESS;
}

char *getDateTime(void)
{
   char *cad = malloc(1024);
   time_t t = time(NULL);
   struct tm *tm = localtime(&t);
   size_t nc;
   
   nc = strftime(cad, 1024, "Date: %a, %d %b %Y %H:%M:%S %Z", tm);
   cad = realloc(cad, nc + 1);
   
   return cad;
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language