我有下面的c代码,它工作正常一次,再次调用该函数后,它给出了相同的结果。缓冲区没有得到更新。
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
char *EpochToMMDDYYYY(long );
int main() {
long epoch = 1492151737;
printf("date of %ld is %s\n",epoch,EpochToMMDDYYYY(epoch));
long ep = 1492222737;
printf("date of %ld is %s\n",epoch,EpochToMMDDYYYY(ep));
long epc = 1491111737;
printf("date of %ld is %s\n",epoch,EpochToMMDDYYYY(epc));
return 0;
}
char *EpochToMMDDYYYY(long ep)
{
struct tm tm;
char b[25];
memset(b,0,sizeof(b));
//setenv("TZ", "PST8PDT", 1);
/* set your own time zone PST8PDT for PDT timezone */
//tzset();
char epoch[20];
sprintf(epoch,"%ld",ep);
memset(&tm, 0, sizeof(struct tm));
strptime(epoch, "%s", &tm);
strftime(b, sizeof(b), "%m%d%Y", &tm);
puts(b); /* -> 04 24 2017 */
return b;
}
输出如下
04142017
date of 1492151737 is 04142017
04142017
date of 1492151737 is 04142017
04022017
date of 1492151737 is 04022017
有人可以告诉我这背后的原因,以及解决方案吗?
答案 0 :(得分:4)
您正在返回指向函数中本地保存的内存的指针:
char *EpochToMMDDYYYY(long ep) {
char b[25];
...
return b;
}
当函数返回时,b
超出范围,不再有效。访问此类内存会导致未定义的行为,并且这种可能的未定义行为可能会产生您的输出。
为了克服这个问题,我看到了两种方法:
首先,您可以将局部变量b
更改为静态,即BLUEPIXY建议的char b[25]; --> static char b[25]
。但请注意,稍后的调用将覆盖先前调用的结果。如果结果没有被复制或最终在同时使用,这可能会有问题:
printf("%s %s", EpochToMMDDYYYY(epoch), EpochToMMDDYYYY(ep))
这将两次打印相同的值,甚至未指定哪一个。
所以,第二,我实际上建议将结果写入的内存作为函数参数传递。更改代码如下:
void EpochToMMDDYYYY(long, char*);
int main() {
char result[25];
long epoch = 1492151737;
EpochToMMDDYYYY(epoch, result);
printf("date of %ld is %s\n",epoch,result);
long ep = 1492222737;
EpochToMMDDYYYY(ep, result);
printf("date of %ld is %s\n",epoch,result);
...
return 0;
}
void *EpochToMMDDYYYY(long ep, char* b) {
...
}