web-dev-qa-db-de.com

Wie wird die Ergebnisstruktur der Ortszeit in C zugeordnet?

Ich habe mit der Datei time.h in C gespielt, die uns bei Zeit-/Tagesfunktionen hilft.

Ich bin auf folgendes gestoßen:

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

... was anscheinend einen Zeiger auf tm struct zurückgibt. Ich habe festgestellt, dass die Rückgabe nach Adresse hauptsächlich zur Rückgabe neuer Speicherzuordnungen verwendet wird.

Wenn dies der Fall ist, wie funktioniert die obige Rückgabe tatsächlich (die Rückgabeadresse eines struct tm)? Ist das zurückgegebene Objekt irgendwo definiert?

Vielen Dank

36
Akash

Der von localtime (und einigen anderen Funktionen) zurückgegebene Zeiger ist tatsächlich ein Zeiger auf den statisch zugewiesenen Speicher. Du musst also nicht befreit werden. Außerdem solltest du es nicht befreien.

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

Diese Struktur wird statisch zugeordnet und von den Funktionen gmtime und localtime gemeinsam genutzt. Bei jedem Aufruf einer dieser Funktionen wird der Inhalt dieser Struktur überschrieben.

EDIT: Ein paar Dinge anhängen, die in den Kommentaren erwähnt werden.

Ein direktes Ergebnis dieser gemeinsamen Datenstruktur ist, dass localtime und ähnliche Funktionen nicht threadsicher sind. Die thread-sichere Lösung variiert je nach Plattform. localtime_r für POSIX und localtime_s für MSVC .

42
Mysticial

Es gibt einen Zeiger auf einen statisch zugewiesenen Speicherbereich zurück (wahrscheinlich entweder eine in static definierte localtime oder eine in der C-Laufzeitbibliothek definierte globale Variable). Sie dürfen diesen Speicher nicht freigeben.

Offensichtlich ist diese Funktion nicht wiedereintrittsfähig (kann aber threadsicher sein, wenn TLS verwendet wird).

Sie müssen vorsichtig sein, wenn Sie diesen Zeiger verwenden: Nehmen Sie niemals Funktionsaufrufe vor, die localtime/gmtime/... aufrufen könnten, bevor Sie diesen Zeiger nicht mehr verwenden. Andernfalls könnte sich der Inhalt des Speichers, auf den Ihr Zeiger verweist, ändern (als Antwort auf den neuen Aufruf) zu localtime) und Sie lesen Werte relativ zu einem anderen time_t.

Im Allgemeinen ist das Design der Datums-/Zeitbibliothek ziemlich veraltet, diese Art der Optimierung hat sich gelohnt, als die C-Sprache entworfen wurde, heutzutage gibt es nur noch Probleme.

Um diese Probleme zu beheben, gibt es mindestens zwei verschiedene verbesserte Versionen dieser Funktionen: localtime_r (SUSv2, r bleibt für "wiedereintrittsfähig") und localtime_s (Microsoft, s bleibt für "sicher"). Die traurige Tatsache für die Portabilität ist, dass diese fast dasselbe tun (sie erfordern, dass das Ziel struct tm als Parameter übergeben wird), sich jedoch in Name und Reihenfolge der Parameter unterscheiden.

11
Matteo Italia

Die Manpage sagt:

Der Rückgabewert zeigt auf eine statisch zugewiesene Struktur, die durch nachfolgende Aufrufe einer beliebigen Datums- und Zeitfunktion überschrieben werden kann.

Ebenfalls:

Die Funktion localtime_r () macht dasselbe, speichert die Daten jedoch in einer benutzerdefinierten Struktur. Es müssen kein Name, keine Zeitzone und kein Tageslicht eingestellt werden.

5
Kos

Tatsächlich gibt localtime normalerweise die Adresse eines statischen Objekts zurück. Ich vermute es sieht so aus:

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

    /* Magic. */

    return &tm;
}
3
cnicutar

Sie geben einen Zeiger auf eine statische Struktur in der Bibliothek zurück. Von der Manpage:

HINWEISE 
 
 Die vier Funktionen asctime (), ctime (), gmtime () und localtime () geben 
 Einen Zeiger auf statische Daten zurück und sind daher nicht threadsicher. Thread-sichere 
 Versionen asctime_r (), ctime_r (), gmtime_r () und localtime_r () sind von SUSv2 spezifiziert - 
 Und verfügbar seit libc 5.2.5. 
 
 POSIX.1-2001 sagt: "Die Funktionen asctime (), ctime (), gmtime () und localtime () 
 Sollen Werte in einem von zwei statischen Objekten zurückgeben: a broken- 
 Ausfallzeitstruktur und ein Array vom Typ char. Die Ausführung einer der 
 Funktionen kann die in einem dieser 
 Objekte zurückgegebenen Informationen durch eine der anderen Funktionen überschreiben. " Dies kann in der Implementierung von glibc 
 Auftreten.
3
Brian Roach

Das von der Funktion localtime zurückgegebene spitze Objekt hat eine statische Speicherdauer.

0
ouah