ángeles washington tiempo pronostico nieva los hoy estado español dias cuando clima california c function pointers struct

washington - ¿Cómo se asigna la estructura del resultado del tiempo local en C?



tiempo de hoy (6)

Estaba jugando con el archivo time.h en C que nos ayuda con las funciones de tiempo / día.

Me encontré con:

struct tm * _Cdecl localtime(const time_t *__timer);

... que parece devolver un puntero a tm struct. Descubrí que la dirección de devolución se usa principalmente para devolver nuevas asignaciones de memoria.

Si esto es así, ¿cómo funciona realmente el retorno anterior (la dirección de retorno de una struct tm ). ¿El objeto devuelto está definido en alguna parte?

Gracias


Devuelve un puntero a una parte de la memoria estáticamente asignada (probablemente una variable static definida dentro de localtime o una global definida en algún lugar de la biblioteca C runtime). No debes liberar tal memoria.

Obviamente, esta función no es reentrante (pero puede ser segura para subprocesos si se usa TLS).

Debe tener cuidado al usar este puntero: nunca haga ninguna llamada a funciones que pueda llamar a gmtime / gmtime / ... antes de que termine de usar ese puntero; de lo contrario, el contenido de la memoria a la que hace referencia el puntero podría cambiar (en respuesta a la nueva llamada) a localtime ) y leerá valores relativos a otro time_t .

En general, el diseño de la biblioteca de fecha / hora está bastante desactualizado, este tipo de optimización valía la pena cuando se diseñó el lenguaje C, hoy en día solo da problemas.

Para solucionar estos problemas hay al menos dos versiones mejoradas diferentes de estas funciones: localtime_r (SUSv2, r permanece para "reentrant") y localtime_s (Microsoft, s permanece como "seguro"). La triste realidad de la portabilidad es que hacen casi lo mismo (requieren que la struct tm destino se pase como un parámetro), pero difieren en el nombre y el orden de los parámetros.


Devuelven un puntero a una estructura estática local a la biblioteca. Desde la página man:

NOTES The four functions asctime(), ctime(), gmtime() and localtime() return a pointer to static data and hence are not thread-safe. Thread-safe versions asctime_r(), ctime_r(), gmtime_r() and localtime_r() are spec‐ ified by SUSv2, and available since libc 5.2.5. POSIX.1-2001 says: "The asctime(), ctime(), gmtime(), and localtime() functions shall return values in one of two static objects: a broken- down time structure and an array of type char. Execution of any of the functions may overwrite the information returned in either of these objects by any of the other functions." This can occur in the glibc implementation.


El objeto puntiagudo que devuelve la función localtime tiene una duración de almacenamiento estática.


El puntero devuelto por localtime (y algunas otras funciones) son en realidad punteros a la memoria asignada estáticamente. Entonces no necesitas liberarte. Además, no deberías liberarlo.

http://www.cplusplus.com/reference/clibrary/ctime/localtime/

Esta estructura está asignada y compartida estáticamente por las funciones gmtime y localtime. Cada vez que se llama una de estas funciones, se sobrescribe el contenido de esta estructura.

EDITAR: Agregar algunas cosas mencionadas en los comentarios.

Un resultado directo de esta estructura de datos compartida es que el tiempo localtime y las funciones similares no son seguras para subprocesos. La solución de seguridad de subprocesos varía según las diferentes plataformas. localtime_r para POSIX y localtime_s para MSVC .


En realidad, localtime generalmente devuelve la dirección de un objeto estático. Sospecho que se ve así:

struct tm * localtime(const time_t *timer) { static struct tm tm; /* Magic. */ return &tm; }


La página man dice:

El valor de retorno apunta a una estructura estáticamente asignada que puede ser sobrescrita por llamadas posteriores a cualquiera de las funciones de fecha y hora.

También:

La función localtime_r () hace lo mismo, pero almacena los datos en una estructura proporcionada por el usuario. No es necesario establecer tzname, zona horaria y luz del día.