【问题标题】:My program output is not getting updated in C我的程序输出没有在 C 中更新
【发布时间】:2017-09-27 03:26:10
【问题描述】:

我的 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

谁能告诉我这背后的原因,以及解决方法?

【问题讨论】:

  • bEpochToMMDDYYYY 函数范围之外无效。
  • 我在哪里可以进行替换以获得准确的输出? @BLUEPIXY
  • char b[25]; --> static char b[25]; 简单修复
  • 返回指向函数返回后不再存在的指针。使用它会导致调用者表现出未定义的行为。
  • 1 谢谢@BLUEPIXY

标签: c pointers memory memory-leaks


【解决方案1】:

您正在返回一个指向函数中本地保存的内存的指针:

char *EpochToMMDDYYYY(long ep) {
    char b[25];
    ...
    return b;
}

当函数返回时,b 超出范围,不再有效。访问此类内存会导致未定义的行为,其中一种可能的未定义行为可能会产生您的输出。

为了克服这个问题,我看到了两种方法:

首先,您可以按照 BLUEPIXY 的建议将局部变量 b 更改为静态,即 char b[25]; --&gt; 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) {
   ...
}

【讨论】:

  • 我现在该怎么办?你能推荐任何替代品吗?
  • 返回char * 可能比void * 更好,因为其目的是将返回值视为字符串(%s)。此外,如果意图是printf("%s %s", EpochToMMDDYYYY(epoch, buffer), EpochToMMDDYYYY(ep, buffer)),那么两次输出将相同。有必要传递不同的缓冲区。
猜你喜欢
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2014-01-24
  • 1970-01-01
相关资源
最近更新 更多