背景:

        需要将起始时间存储下来(要求格式为年-月-日-时:分:秒),以便下次进入循环时能与当前时间做比较。

解决方案:

        显然就是调用linux的localtime时间函数(参考文献1)的,于是乎写出了如下的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

struct tm* old_time;

void InitTime(void)
{
	time_t timep;
	time(&timep);
	old_time = localtime(&timep);	
}

int main(int argc, char* argv[])
{
	time_t timep;
	struct tm* p;
	InitTime();
	while(1){
		time(&timep);
		p = localtime(&timep);
		if(memcmp(p, old_time, sizeof(struct tm))==0){
			printf("Same %d\n",old_time->tm_sec);
		}
		else{
			printf("Different %d\n", old_time->tm_sec);
			memcpy(old_time, p, sizeof(struct tm));
		}
		int i, j;
		for(i=0; i<100000;++i)
			for(j=0; j<1000;++j);

	}
	return 0;
}

        但运行结果,总是打印“Same”而且秒数一直在递增,很是奇怪。

       经过分析以及调研后,发现localtime返回的是一个地址,指向内核申请的一个固定地址,所以old_time和p都是指向同一个地方,所以memcmp的返回值肯定是0。

        为了达到目的,可行的解决方法就是将每次localtime返回后立即将“时间内容”存储到本地保存。如下所示。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

struct tm* old_time;

void InitTime(void)
{
	time_t timep;
	time(&timep);
	//old_time = localtime(&timep);
	old_time = (struct tm*)malloc(sizeof(struct tm));
	memcpy(old_time, localtime(&timep), sizeof(struct tm));
}

int main(int argc, char* argv[])
{
	time_t timep;
	struct tm* p;
	p = (struct tm*)malloc(sizeof(struct tm));
	InitTime();
	while(1){
		time(&timep);
		//p = localtime(&timep);
		memcpy(p, localtime(&timep), sizeof(struct tm));
		if(memcmp(p, old_time, sizeof(struct tm))==0){
			printf("Same %d\n",old_time->tm_sec);
		}
		else{
			printf("Different %d\n", old_time->tm_sec);
			memcpy(old_time, p, sizeof(struct tm));
		}
		int i, j;
		for(i=0; i<100000;++i)
			for(j=0; j<1000;++j);

	}
	return 0;
}

       于是,对localtime更进一步的探寻,本来是希望能够找出localtime的内部实现的,但从GUN的FTP上下下来后表示看不懂,待看懂的时候再来更新此博文。

/* Convert `time_t' to `struct tm' in local time zone.
   Copyright (C) 1991,92,93,95,96,97,98,2002 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <time.h>

/* The C Standard says that localtime and gmtime return the same pointer.  */
struct tm _tmbuf;


/* Return the `struct tm' representation of *T in local time,
   using *TP to store the result.  */
struct tm *
__localtime_r (t, tp)
     const time_t *t;
     struct tm *tp;
{
  return __tz_convert (t, 1, tp);
}
weak_alias (__localtime_r, localtime_r)


/* Return the `struct tm' representation of *T in local time.  */
struct tm *
localtime (t)
     const time_t *t;
{
  return __tz_convert (t, 1, &_tmbuf);
}
libc_hidden_def (localtime)

总结

        折腾好一会儿总算是解决了,感觉还是自己太马虎,既然返回的是一个地址,就应该敏锐注意到不能随意使用,毕竟所调用的函数也掌握了该地址,可以对其任意更改甚至销毁。

参考文献

[1] http://www.cnblogs.com/xmphoenix/archive/2011/05/09/2041546.html



Logo

更多推荐