Как создается результирующая структура локального времени в C?

Я играл с файлом time.h в C, который помогает нам с функциями времени/дня.

Я наткнулся:

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

... который, кажется, возвращает указатель на tm struct. Я обнаружил, что возвращение по адресу в основном используется для возврата новых распределений памяти.

Если это так, как работает вышеуказанный возврат (обратный адрес struct tm). Является ли возвращаемый объект определенным?

Спасибо

Ответ 1

Указатель, возвращаемый localtime (и некоторыми другими функциями), на самом деле указывает на статически выделенную память. Так что вам не нужно освобождать. Кроме того, вы не должны его освобождать.

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

Эта структура статически распределена и разделяется функциями gmtime и localtime. Каждый раз, когда одна из этих функций называемый содержимым этой структуры, перезаписывается.

EDIT: Добавление нескольких замечаний, упомянутых в комментариях.

Прямым результатом этой общей структуры данных является то, что localtime и подобные функции не являются потокобезопасными. Потоковое решение зависит от разных платформ. localtime_r для POSIX и localtime_s для MSVC.

Ответ 2

Он возвращает указатель на часть статически выделенной памяти (возможно, либо переменную static, определенную внутри localtime, либо глобальную, определенную где-то в библиотеке времени выполнения C). Вы не должны освобождать такую ​​память.

Очевидно, что эта функция не является реентерабельной (но может быть потокобезопасной, если используется TLS).

Вы должны быть осторожны при использовании этого указателя: никогда не делайте никаких вызовов функций, которые могли бы вызвать localtime/gmtime/... до того, как вы закончите использовать этот указатель, в противном случае содержимое памяти, на которое ссылается ваш указатель, может измениться (в ответ на новый вызов localtime), и вы будете считывать значения относительно другого time_t.

В целом дизайн библиотеки даты и времени довольно устарел, такая оптимизация была полезной, когда язык C был разработан, в настоящее время он только создает проблемы.

Для решения этих проблем есть как минимум две различные улучшенные версии этих функций: localtime_r (SUSv2, r остается для "повторного" ) и localtime_s (Microsoft, s остается "безопасным" ), Печальный факт для переносимости состоит в том, что они выполняют почти одно и то же (они требуют, чтобы пункт назначения struct tm передавался как параметр), но различаются по имени и порядку параметров.

Ответ 3

В справочной странице говорится:

Возвращаемое значение указывает на статически выделенную структуру, которая может быть перезаписана последующими вызовами любой из функций даты и времени.

также:

Функция localtime_r() делает то же самое, но сохраняет данные в предоставленной пользователем структуре. Не нужно устанавливать tzname, часовой пояс и дневной свет.

Ответ 4

Фактически localtime обычно возвращает адрес статического объекта. Я подозреваю, что это выглядит так:

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

    /* Magic. */

    return &tm;
}

Ответ 5

Они возвращают указатель на статическую структуру, локальную в библиотеку. На странице 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.

Ответ 6

Указанный объект, возвращаемый функцией localtime, имеет статическую продолжительность хранения.