localtime函数中的返回指针的思考
2011-11-25 14:30
183 查看
localtime和gmtime这两个函数采用了time.h中的一个tm结构体:
struct tm
{
int tm_sec; /* Seconds. [0-60] (1 leap second) */
int tm_min; /* Minutes. [0-59] */
int tm_hour; /* Hours. [0-23] */
int tm_mday; /* Day. [1-31] */
int tm_mon; /* Month. [0-11] */
int tm_year; /* Year - 1900. */
int tm_wday; /* Day of week. [0-6] */
int tm_yday; /* Days in year.[0-365] */
int tm_isdst; /* DST. [-1/0/1]*/
};
这两个函数的原型为:
struct tm *localtime(const time_t *timep);
struct tm *gmtime(const time_t *timep);
例1:
---------------------------------------------------------
#include <ctime>
#include <iostream>
using namespace std;
void cur_time(void)
{
char *wday[] = {"星期天", "星期一","星期二","星期三","星期四","星期五","星期六"};
time_t timep;
struct tm *p;
time(&timep);
p = localtime(&timep);
printf("%d年%2d月%2d日", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
printf("%s%2d:%2d:%2d/n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
}
int main()
{
cur_time();
return 0;
}
---------------------------------------------------------
运行结果为:
2008年12月26日星期三 11:07:15
例2《一个关于localtime函数的讨论》:
---------------------------------------------------------
#include <ctime>
#include <iostream>
using namespace std;
struct tm* get_local_time()
{
struct tm *now;
time_t timep;
time(&timep);
now = localtime(&timep);
return now;
}
int main()
{
struct tm *temp;
struct tm *temp1;
//struct tm tm1;
//struct tm tm2;
temp = get_local_time();
//tm1 = *temp;
printf("%d:%2d:%2d/n", temp->tm_hour, temp->tm_min, temp->tm_sec);
//目的是停顿一下
getchar();
//tm2 = *temp1;
temp1 = get_local_time();
printf("%d:%2d:%2d/n", temp->tm_hour, temp->tm_min, temp->tm_sec);
printf("%d:%2d:%2d/n", temp1->tm_hour, temp1->tm_min, temp1->tm_sec);
//printf("%d:%2d:%2d/n", temp->tm_hour, temp->tm_min, temp->tm_sec);
//printf("%d:%2d:%2d/n", temp1->tm_hour, temp1->tm_min, temp1->tm_sec);
return 0;
}
---------------------------------------------------------
运行结果为:
最后两个printf()结果是一样的
其原因如下:
这是localtime函数实现的问题。
该函数返回的是一个指针,表示某一个地址。大家知道,如果是一个非静态的局部变量,返回它的地址是错误的做法,因为非静态的局部变量在函数返回时,已经被销毁了,它的地址成为无用的地址。因此localtime函数返回的指针只有以下三种可能:要么是一个静态变量的地址,要么是一个全局变量的地址,或者是使用malloc等函数在堆上分配的空间。
对于最后一种情况,因为标准并没有规定可以对localtime返回的地址进行free,所以如果localtime函数是使用malloc函数分配空间的话,程序员不会使用free函数去释放它,因此造成内存泄露,这是不好的做法。
前两种情况其实是非常相似的,这里仅以第一种情况来做说明。如果localtime函数使用静态变量,则它大致像下面这个样子:
struct tm* localtime(const time_t* ptr)
{
static struct tm ret;
// 在这里计算并得到ret的值
return &ret;
}
如果真是这样的话,不论调用多少次localtime,则它返回的地址都是一样的。只是地址中保存的内容可能不同而已。
比较正确的做法是:
struct tm* temp;
struct tm* temp1;
struct tm tm1;
struct tm tm2;
temp = get_local_time();
tm1 = *temp;
sleep(3);
temp1 = get_local_time();
tm2 = *temp1;
则虽然可能有temp == temp1,但是tm1和tm2则会不同。
静态变量在进行多线程编程时是危险的,因此微软搞出了一个新的localtime_s函数来取代localtime函数(新版本的VC有这个函数,VC 6.0则似乎没有,linux系统我并不清楚)。这两个函数在功能上一致,只是localtime返回地址,而localtime_s是传入一个地址,让函数填充其内容。后者不需要使用静态变量,在多线程的情况下更安全。
例3 用localtime_s()代替localtime():
---------------------------------------------------------
#include <ctime>
#include <iostream>
using namespace std;
int main()
{
struct tm newtime;
time_t timep;
errno_t err;
time(&timep);
err = localtime_s(&newtime, &timep);
if (err)
{
printf("Invalid argument to localtime_s.");
return;
}
else
{
printf("%d:%2d:%2d/n", newtime.tm_hour, newtime.tm_min, newtime.tm_sec);
}
return 0;
}
---------------------------------------------------------
例4 gmtime()函数
---------------------------------------------------------
#include <ctime>
#include <iostream>
using namespace std;
void cur_time(void)
{
char *wday[] = {"星期天", "星期一","星期二","星期三","星期四","星期五","星期六"};
time_t timep;
struct tm *p;
time(&timep);
p = gmtime(&timep);
printf("%d年%2d月%2d日", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
printf("%s%2d:%2d:%2d/n", wday[p->tm_wday], p->tm_hour + 8, p->tm_min, p->tm_sec);
}
int main()
{
cur_time();
return 0;
}
struct tm
{
int tm_sec; /* Seconds. [0-60] (1 leap second) */
int tm_min; /* Minutes. [0-59] */
int tm_hour; /* Hours. [0-23] */
int tm_mday; /* Day. [1-31] */
int tm_mon; /* Month. [0-11] */
int tm_year; /* Year - 1900. */
int tm_wday; /* Day of week. [0-6] */
int tm_yday; /* Days in year.[0-365] */
int tm_isdst; /* DST. [-1/0/1]*/
};
这两个函数的原型为:
struct tm *localtime(const time_t *timep);
struct tm *gmtime(const time_t *timep);
例1:
---------------------------------------------------------
#include <ctime>
#include <iostream>
using namespace std;
void cur_time(void)
{
char *wday[] = {"星期天", "星期一","星期二","星期三","星期四","星期五","星期六"};
time_t timep;
struct tm *p;
time(&timep);
p = localtime(&timep);
printf("%d年%2d月%2d日", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
printf("%s%2d:%2d:%2d/n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
}
int main()
{
cur_time();
return 0;
}
---------------------------------------------------------
运行结果为:
2008年12月26日星期三 11:07:15
例2《一个关于localtime函数的讨论》:
---------------------------------------------------------
#include <ctime>
#include <iostream>
using namespace std;
struct tm* get_local_time()
{
struct tm *now;
time_t timep;
time(&timep);
now = localtime(&timep);
return now;
}
int main()
{
struct tm *temp;
struct tm *temp1;
//struct tm tm1;
//struct tm tm2;
temp = get_local_time();
//tm1 = *temp;
printf("%d:%2d:%2d/n", temp->tm_hour, temp->tm_min, temp->tm_sec);
//目的是停顿一下
getchar();
//tm2 = *temp1;
temp1 = get_local_time();
printf("%d:%2d:%2d/n", temp->tm_hour, temp->tm_min, temp->tm_sec);
printf("%d:%2d:%2d/n", temp1->tm_hour, temp1->tm_min, temp1->tm_sec);
//printf("%d:%2d:%2d/n", temp->tm_hour, temp->tm_min, temp->tm_sec);
//printf("%d:%2d:%2d/n", temp1->tm_hour, temp1->tm_min, temp1->tm_sec);
return 0;
}
---------------------------------------------------------
运行结果为:
最后两个printf()结果是一样的
其原因如下:
这是localtime函数实现的问题。
该函数返回的是一个指针,表示某一个地址。大家知道,如果是一个非静态的局部变量,返回它的地址是错误的做法,因为非静态的局部变量在函数返回时,已经被销毁了,它的地址成为无用的地址。因此localtime函数返回的指针只有以下三种可能:要么是一个静态变量的地址,要么是一个全局变量的地址,或者是使用malloc等函数在堆上分配的空间。
对于最后一种情况,因为标准并没有规定可以对localtime返回的地址进行free,所以如果localtime函数是使用malloc函数分配空间的话,程序员不会使用free函数去释放它,因此造成内存泄露,这是不好的做法。
前两种情况其实是非常相似的,这里仅以第一种情况来做说明。如果localtime函数使用静态变量,则它大致像下面这个样子:
struct tm* localtime(const time_t* ptr)
{
static struct tm ret;
// 在这里计算并得到ret的值
return &ret;
}
如果真是这样的话,不论调用多少次localtime,则它返回的地址都是一样的。只是地址中保存的内容可能不同而已。
比较正确的做法是:
struct tm* temp;
struct tm* temp1;
struct tm tm1;
struct tm tm2;
temp = get_local_time();
tm1 = *temp;
sleep(3);
temp1 = get_local_time();
tm2 = *temp1;
则虽然可能有temp == temp1,但是tm1和tm2则会不同。
静态变量在进行多线程编程时是危险的,因此微软搞出了一个新的localtime_s函数来取代localtime函数(新版本的VC有这个函数,VC 6.0则似乎没有,linux系统我并不清楚)。这两个函数在功能上一致,只是localtime返回地址,而localtime_s是传入一个地址,让函数填充其内容。后者不需要使用静态变量,在多线程的情况下更安全。
例3 用localtime_s()代替localtime():
---------------------------------------------------------
#include <ctime>
#include <iostream>
using namespace std;
int main()
{
struct tm newtime;
time_t timep;
errno_t err;
time(&timep);
err = localtime_s(&newtime, &timep);
if (err)
{
printf("Invalid argument to localtime_s.");
return;
}
else
{
printf("%d:%2d:%2d/n", newtime.tm_hour, newtime.tm_min, newtime.tm_sec);
}
return 0;
}
---------------------------------------------------------
例4 gmtime()函数
---------------------------------------------------------
#include <ctime>
#include <iostream>
using namespace std;
void cur_time(void)
{
char *wday[] = {"星期天", "星期一","星期二","星期三","星期四","星期五","星期六"};
time_t timep;
struct tm *p;
time(&timep);
p = gmtime(&timep);
printf("%d年%2d月%2d日", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
printf("%s%2d:%2d:%2d/n", wday[p->tm_wday], p->tm_hour + 8, p->tm_min, p->tm_sec);
}
int main()
{
cur_time();
return 0;
}
相关文章推荐
- linux上localtime函数返回的指针
- localtime()函数返回的指针如何释放的?
- c++中函数中变量内存分配以及返回指针、引用类型的思考
- 函数的返回类型为指针类型时的若干思考(字符串常量问题)
- 为什么localtime()函数返回的指针不需要释放?
- c++中函数中变量内存分配以及返回指针、引用类型的思考
- 函数的返回类型为指针类型时的若干思考(字符串常量问题)
- 返回指针的函数
- 【php数组函数序列】之prev() - 移动数组内部指针到上一个元素的位置,并返回该元素值
- 杜绝返回函数内局部变量的指针或引用
- 如果从函数中返回局部变量的地址,引用或者指针的形式,则变量类型必须是静态的或者常量,即不在栈中存储
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- c语言指向函数的指针和返回指针的函数
- 【C语言】14-返回指针的函数与指向函数的指针
- 函数返回一个指针
- c++从函数返回指针
- 转:关于函数指针数组与返回数组指针的函数
- php数组函数序列之prev() - 移动数组内部指针到上一个元素的位置,并返回该元素值
- 返回指针值的函数
- 关于qsort第四个参数,函数指针作参数的一点思考