我的程序输出没有在C中更新

时间:2017-04-28 22:49:21

标签: c pointers memory memory-leaks

我有下面的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

有人可以告诉我这背后的原因,以及解决方案吗?

1 个答案:

答案 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) {
   ...
}