Как структура результата локального времени размещается в C? - PullRequest
36 голосов
/ 01 января 2012

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

Я сталкивался:

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

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

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

Спасибо

Ответы [ 6 ]

44 голосов
/ 01 января 2012

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

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

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

РЕДАКТИРОВАТЬ: Добавление нескольких вещей, упомянутых в комментариях.

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

11 голосов
/ 01 января 2012

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

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

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

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

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

5 голосов
/ 01 января 2012

Справочная страница говорит:

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

Также:

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

3 голосов
/ 01 января 2012

Они возвращают указатель на статическую структуру, локальную для библиотеки.Со страницы руководства:

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.
3 голосов
/ 01 января 2012

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

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

    /* Magic. */

    return &tm;
}
0 голосов
/ 01 января 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...