函数ctime
的原型是:
char *ctime(const time_t *timep);
我们可以看到,它返回一个字符串。但是,这个字符串被包含在哪里呢?
为什么我们不应该释放这个字符串的内存。
这段示例代码会产生很多错误消息。
char *p;
p = ctime(...);
...
free(p);
*** glibc 检测到 *** ./a.out:free():无效指针:0x00007f0b365b4e60 ***
函数ctime
的原型是:
char *ctime(const time_t *timep);
我们可以看到,它返回一个字符串。但是,这个字符串被包含在哪里呢?
为什么我们不应该释放这个字符串的内存。
这段示例代码会产生很多错误消息。
char *p;
p = ctime(...);
...
free(p);
*** glibc 检测到 *** ./a.out:free():无效指针:0x00007f0b365b4e60 ***
该函数返回一个指向静态
缓冲区的指针,不得进行free()
操作。来自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()
函数调用返回的指针,否则行为未定义。
它指向静态数据,没有使用malloc函数。
p
没有使用 malloc
或者 calloc
进行动态分配,所以你没有请求分配 堆内存
来进行 释放
。p
只是一个指向之前分配的某个内存的普通指针(所以对你来说是可用的)。ctime()
的变量应该在其他地方创建,创建者是借给你的指针 p
的资源的所有者,所以你的指针只是一个 观察者
,不是一个 资源所有者
,所以没有需要从你的指针中释放的内容。
[][4]
(或者更好的选择是指针数组,以避免这个错误)。 - unwind