переменная time_t и char* неожиданно перезаписывается

Следующий код

{
    time_t t;
    t = time(NULL);
    char *A;
    A = ctime(&t);
    printf("%s -\n", A);
    sleep(2);
    time_t t1;
    t1 = time(NULL);
    printf("%s HERE A =\n", A);
    char *B = ctime(&t1);
    printf("%s HERE B =\n", B);
    printf("%s\n", B);
}

имеет вывод

Sat Mar 30 19:10:33 2019
 -
Sat Mar 30 19:10:33 2019
 HERE A =
Sat Mar 30 19:10:35 2019
 HERE B =
Sat Mar 30 19:10:35 2019

Так как же меняется переменная A? что мне нужно сделать, чтобы A оставалось с фиксированным значением

замена char *A; на const char *A; не помогает

ожидал

Sat Mar 30 19:10:33 2019
 -
Sat Mar 30 19:10:33 2019
 HERE A =
Sat Mar 30 19:10:33 2019
 HERE B =
Sat Mar 30 19:10:35 2019

person raunaque patra    schedule 30.03.2019    source источник
comment
Функция ctime не является реентерабельный. У него есть только один буфер, который он использует повторно. Указатель, который он возвращает, является указателем на первый символ этого единственного буфера.   -  person Some programmer dude    schedule 30.03.2019


Ответы (1)


Итак, ctime возвращает указатель на строку. Вы назначаете этот указатель A и B. В этом случае он возвращает один и тот же указатель, то есть A и B указывают на один и тот же адрес в памяти. Вы можете увидеть это, если добавите код для печати адреса:

printf("A=0x%x, B=0x%x", A, B);

Страница руководства для time объясняет, что это поведение, на которое следует обратить внимание:

Возвращаемое значение указывает на статически выделенную строку, которая может быть перезаписана последующими вызовами любой из функций даты и времени. Функция также устанавливает внешние переменные tzname, timezone и daylight (см. tzset(3)) с информацией о текущем часовом поясе. Реентерабельная версия ctime_r() делает то же самое, но сохраняет строку в предоставленном пользователем буфере, в котором должно быть место не менее 26 байт. Ему не нужно устанавливать tzname, часовой пояс и дневной свет.

Итак, чтобы исправить это, вы можете использовать реентерабельную версию ctime вместо ctime_r:

char C[27];
ctime_r(&t1, &C);

Вы также можете использовать strcpy или strdup, чтобы скопировать его в свою собственную строку, которая не будет перезаписана.

Вот еще один ответ, касающийся этого: Сохранение новых точек в время с ctime перезаписывает старые строки?

person Tony Biondo    schedule 30.03.2019