ctime() возвращает строку, почему нам не нужно освобождать память этой строки?

прототип функции ctime есть

char *ctime(const time_t *timep);

Как мы видим, он возвращает строку. но где утаить жало?

и почему мы не должны освобождать память строки

Это пример кода, который получит много сообщений об ошибках.

char *p;
p = ctime(...);
...
free(p);

*** Обнаружен glibc *** ./a.out: free(): неверный указатель: 0x00007f0b365b4e60 ***


person thlgood    schedule 29.06.2012    source источник


Ответы (2)


Он возвращает указатель на буфер static и не должен быть free()d. Из man ctime:

Четыре функции asctime(), ctime(), gmtime() и localtime() возвращают указатель на статические данные и, следовательно, не являются потокобезопасными.

В стандарте C99, раздел 7.23.3.2 Функция ctime, указано, что вызов функции ctime(timer) эквивалентен asctime(localtime(timer)), а реализация asctime() (как показано в том же документе) эквивалентна следующему:

char *asctime(const struct tm *timeptr)
{
    static const char wday_name[7][3] = {
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
    };

    static const char mon_name[12][3] = {
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };

    static char result[26];
    sprintf(result,
            "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
            wday_name[timeptr->tm_wday],
            mon_name[timeptr->tm_mon],
            timeptr->tm_mday, timeptr->tm_hour,
            timeptr->tm_min, timeptr->tm_sec,
            1900 + timeptr->tm_year);

    return result;
}

Аргумент, передаваемый free(), должен быть указателем, возвращаемым вызовом только malloc(), calloc() или realloc(), иначе поведение не определено.

person hmjd    schedule 29.06.2012
comment
Просто добавьте, что если вам нужна поточно-ориентированная версия, используйте вместо этого ctime_r(). - person Turix; 29.06.2012
comment
@Turix, да, это указано на связанной странице. - person hmjd; 29.06.2012
comment
Я действительно думаю, что эти массивы [][4] (или, что еще лучше, массивы указателей, чтобы избежать этой ошибки). - person unwind; 29.06.2012
comment
Итак, его размещение в глобальной памяти. Разве это не будет заполнено, когда мы будем вызывать функцию снова и снова? - person Vamshi; 10.11.2014
comment
@Vamshi Да, было бы лучше скопировать данные из статической памяти сразу после вызова. - person Tyler Kropp; 05.01.2021

Он указывает на статические данные и не был преобразован в malloc.

person pizza    schedule 29.06.2012