39 votes

Comment la structure de résultat de localtime est-elle allouée en C ?

Je jouais avec le time.h en C qui nous aide avec les fonctions heure/jour.

Je suis tombé dessus :

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

...qui semble retourner un pointeur vers la structure tm. J'ai constaté que le retour par adresse est surtout utilisé pour retourner les nouvelles allocations de mémoire.

Si c'est le cas, comment fonctionne réellement le retour ci-dessus (l'adresse de retour d'un struct tm ). L'objet retourné est-il défini quelque part ?

Gracias

54voto

Mysticial Points 180300

Le pointeur renvoyé par localtime (et quelques autres fonctions) sont en fait des pointeurs vers de la mémoire allouée statiquement. Vous n'avez donc pas besoin de le libérer, et vous ne devriez pas le libérer.

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

Cette structure est allouée statiquement et partagée par les fonctions gmtime et localtime. Chaque fois que l'une de ces fonctions est appelée, le contenu de cette structure est écrasé.

EDIT : Ajout de quelques éléments mentionnés dans les commentaires.

Une conséquence directe de cette structure de données partagée est que localtime et d'autres fonctions similaires ne sont pas sûres pour les fils. La solution thread-safe varie selon les plateformes. localtime_r pour POSIX y localtime_s pour MSVC .

12voto

Matteo Italia Points 53117

Elle renvoie un pointeur vers un morceau de mémoire allouée statiquement (probablement soit un static variable définie dans localtime ou un global défini quelque part dans la bibliothèque d'exécution C). Vous ne devez pas libérer une telle mémoire.

Évidemment, cette fonction n'est pas réentrante (mais peut être thread-safe si TLS est utilisé).

Vous devez être prudent lorsque vous utilisez ce pointeur : ne faites jamais d'appels de fonction qui pourraient appeler localtime / gmtime /... avant d'avoir fini d'utiliser ce pointeur, sinon le contenu de la mémoire référencée par votre pointeur pourrait changer (en réponse au nouvel appel à localtime ) et vous lirez des valeurs relatives à une autre time_t .

En général, la conception de la bibliothèque date/heure est assez dépassée, ce genre d'optimisation valait la peine lorsque le langage C a été conçu, aujourd'hui elle ne pose que des problèmes.

Pour résoudre ces problèmes, il existe au moins deux versions améliorées différentes de ces fonctions : localtime_r (SUSv2, r séjours pour "réentrant") et localtime_s (Microsoft, s reste pour "sûr"). La triste réalité pour la portabilité est que ceux-ci font presque la même chose (ils exigent que la destination struct tm à passer en tant que paramètre), mais diffèrent dans le nom et l'ordre des paramètres.

5voto

Kos Points 29125

El page de manuel dit :

La valeur de retour pointe vers une structure allouée statiquement qui pourrait être écrasée par des appels ultérieurs à l'une des fonctions de date et d'heure.

Aussi :

La fonction localtime_r() fait la même chose, mais stocke les données dans une structure fournie par l'utilisateur. Il n'est pas nécessaire de définir le tzname, le fuseau horaire et la lumière du jour.

3voto

cnicutar Points 98451

En fait, localtime renvoie généralement l'adresse d'un objet statique. Je suppose que ça ressemble à ça :

struct tm *
localtime(const time_t *timer)
{
    static struct tm tm;

    /* Magic. */

    return &tm;
}

3voto

Brian Roach Points 43787

Ils renvoient un pointeur vers une structure statique locale à la bibliothèque. De la page de manuel :

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X