Ver Mensaje Individual
  #3 (permalink)  
Antiguo 27/12/2013, 11:53
vosk
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 12 años, 3 meses
Puntos: 83
Respuesta: Problemas funciones obtención hora y fecha local

@vangodp: 'struct tm' es una estructura estandar definida en time.h, pero tienes razon: usa dos punteros sobre una misma cosa.

El problema está en que la funcion 'localtime' escribe sobre una unica estructura interna a la libreria, pero solo te retorna un puntero a esa estructura. Para que se vea mejor puedes cambiar los nombres de las variables:

Código C:
Ver original
  1. time_t t1,t2;
  2. struct tm *puntero1;
  3. struct tm *puntero2;
  4.  
  5. time(&t1);
  6. puntero1 = localtime(&t1);//guardas en una estructura interna unica y recibes el puntero
  7.  
  8. time(&t2);
  9. puntero2 = localtime(&t2);//sobreescribes la estructura interna y recibes el puntero

Ambos punteros apuntan a una misma estructura, cuya direccion es constante para esta instancia de la aplicacion, eso significa que puntero1 apunta al mismo sitio que puntero2, o traducido a tu codigo significa que tinfo1 es lo mismo que tinfo2 despues de que ejecutes el segundo localtime.

Supongo que quieres calcular el tiempo de ejecucion. Puedes solucionarlo de dos formas: o bien creas un struct tm y copias literalmente el retorno de localtime, o usas los timestamps. Normalmente se usan los timestamps. Un ejemplo con las estructuras:

Código C:
Ver original
  1. time_t t1,t2;
  2. struct tm *ptr1, *ptr2;
  3. struct tm tinfo1, tinfo2;
  4. char f1[TFECHA],f2[TFECHA];
  5.  
  6. time(&t1);
  7. ptr1 = localtime(&t1);
  8. memcpy(&tinfo1, ptr1, sizeof(struct tm));
  9.  
  10. strftime(f1, TFECHA, "%d/%m/%Y %H:%M:%S", &tinfo1);
  11. printf("%s\n", f1);
  12.  
  13. Sleep(5000);
  14.  
  15. time(&t2);
  16. ptr2 = localtime(&t2);
  17. memcpy(&tinfo2, ptr2, sizeof(struct tm));
  18.  
  19. strftime(f1, TFECHA, "%d/%m/%Y %H:%M:%S", &tinfo1);
  20. strftime(f2, TFECHA, "%d/%m/%Y %H:%M:%S", &tinfo2);
  21. printf("%s\n%s", f1,f2);

Y ahora uno con los timestamps:

Código C:
Ver original
  1. clock_t t1, t2;
  2.  
  3. printf("Entre ahora... ");
  4. t1 = clock();
  5.  
  6. Sleep(5000);
  7. printf("y ahora han pasado ");
  8.  
  9. t2 = clock() - t1;
  10. printf("%f segundos\n", ((float)t2) / CLOCKS_PER_SEC);

Una ultima cosa: cuando usas una libreria donde alguna funcion te retorna un puntero tienes que prever dos cosas. La primera, que puede haber en esa libreria una funcion para liberar la posible memoria bloqueda para el puntero. La segunda, que si no hay funciones de liberacion de memoria ni en la referencia de las funciones te indica que debes liberar la memoria entonces significa que ese puntero está apuntando a un sitio unico (o eso o la libreria está mal documentada, que tambien puede ser). En el caso de localtime te retorna un puntero pero no te dice que al finalizar su uso debes liberar la memoria: eso indica que te retorna un puntero a una direccion de memoria unica para la instancia de tu aplicacion, es decir que cada vez que llames a localtime se sobreescribirá esa direccion.

Este tipo de funciones se dice que no son thread-safe, es decir que no esperes que funcione cuando los uses en una aplicacion en multiprocesos sin semaforos o zonas criticas (ya se que el codigo que colgaste no es multithread, ahí funciona pero funciona mal). Te gustará saber que tambien la funcion strtok es de ese tipo.

Saludos
vosk

Última edición por vosk; 27/12/2013 a las 12:06