【问题标题】:Strange behavior of mktime() when using passing parameter created by malloc使用 malloc 创建的传递参数时 mktime() 的奇怪行为
【发布时间】:2020-04-23 13:47:13
【问题描述】:

下面我有四个函数。
first()second()只初始化结构tm的年、月、日。
first_p()second_p使用malloc分配内存,然后赋值年,周一和 mday。
所有函数最后都调用mktime()

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void first()
{
    int year1 = 2020, month1 = 4, day1 = 23;
    struct tm date1 = {.tm_year = year1-1900, .tm_mon = month1-1, .tm_mday = day1};
    mktime(&date1);
    printf("%s", asctime(&date1));
}

void second()
{
    int year2 = 2021, month2 = 5, day2 = 24;
    struct tm date2 = {.tm_year = year2-1900, .tm_mon = month2-1, .tm_mday = day2};
    mktime(&date2);
    printf("%s", asctime(&date2));
}

void first_p()
{
    int year1 = 2020, month1 = 4, day1 = 23;
    struct tm *date1 = (struct tm *) malloc (sizeof(struct tm));
    date1->tm_year = year1 - 1900;
    date1->tm_mon = month1 -1;
    date1->tm_mday = day1;
    mktime(date1);
    printf("%s", asctime(date1));
}

void second_p()
{
    int year2 = 2021, month2 = 5, day2 = 24;
    struct tm *date2 = (struct tm *) malloc (sizeof(struct tm));
    date2->tm_year = year2 - 1900;
    date2->tm_mon = month2 - 1;
    date2->tm_mday = day2;
    mktime(date2);
    printf("%s", asctime(date2));
}

我在main() 中调用这些函数时尝试了不同的排列:

1) first_p()second_p() 显示随机日期和时间。

int main()
{
    first();
    second();
    first_p();
    second_p();

    return 0;
}
Thu Apr 23 00:00:00 2020
Mon May 24 00:00:00 2021
Thu Sep 30 23:09:20 66488
Wed Aug 31 14:44:48 66489

2) 只有second_p() 显示随机日期和时间。

int main()
{
    first_p();
    second_p();
    first();
    second();

    return 0;
}
Thu Apr 23 00:00:00 2020
Sun Dec  8 01:26:16 -103880
Thu Apr 23 00:00:00 2020
Mon May 24 00:00:00 2021

3) 只有second_p() 显示随机日期和时间。

int main()
{
    first_p();
    first();
    second();
    second_p();

    return 0;
}
Thu Apr 23 00:00:00 2020
Thu Apr 23 00:00:00 2020
Mon May 24 00:00:00 2021
Thu Oct  9 04:53:52 60110

4) first_p()second_p() 显示随机日期和时间。

int main()
{
    first();
    first_p();
    second_p();
    second();

    return 0;
}
Thu Apr 23 00:00:00 2020
Sat Sep 25 12:05:36 182934
Fri Aug 26 03:41:04 182935
Mon May 24 00:00:00 2021

我观察到的是:

  • 直接初始化结构,然后将其传递给 mktime() 任何地方都没有奇怪的行为。
  • 使用 malloc 分配内存,然后分配值,然后将其传递给 mktime() 有两种行为:
    • 如果是第一次调用 mktime(),则不会出现异常行为。
    • 否则它会显示一些随机日期和时间。有时年份是负数!

我是否遗漏了导致此行为的有关 mktime() 的某些内容?

编辑:
我在first_p()second_p() 的末尾添加了free(date1);free(date2);。现在一个接一个地调用*_p() 函数不会显示随机日期和时间。然而,在它们之前调用first()second() 函数会显示第一个*_p() 函数的随机日期和时间,而后面的函数则不会,即上面列出的情况1)、3) 和4)。

但是,不能释放它,因为我在其他地方需要它们(为什么我必须首先使用 malloc)。有没有办法实现?

【问题讨论】:

  • 填写结构的所有字段。 malloc 不会为您这样做;它不会将内存设置为零或以其他方式为您初始化它。 (在函数内部定义结构也不会默认初始化它,但是,如果您为某些字段提供初始值,则其他字段将初始化为零。)
  • mallocd 内存初始化。将其设置为零,或致电calloc

标签: c date malloc mktime time.h


【解决方案1】:

malloc() 数据中的小时、分钟、秒和夏令时标志中有准随机(不确定)值,因此您可以从 mktime() 返回不确定的结果。

使用calloc() 代替malloc(),或者自己将字段归零。

另外,考虑将tm_isdst 成员设置为-1 以让系统确定日期是否适合夏令时或标准时间。

【讨论】:

  • 谢谢!使用calloc() 解决了这个问题。但是,我仍然不明白为什么第一次调用 mktime() 时没有这样的随机行为,无论我使用 malloc() 还是 calloc(),即在我提到的情况 3) 和 4) 中.
  • 使用指定的初始化器初始化局部变量后,未显式初始化的字段被隐式(但明确地)归零。使用malloc() 内存,您不知道自己拥有什么——使用calloc() 有效地使用memset() 将内存归零,因此您也可以这样做。您可以将年、月、日、小时、分钟、秒和 DST 字段设置为零(或其他已知值),并且需要 mktime() 才能工作。它在确定时间时不会关注“一年中的某一天”或“一周中的某一天”字段,但会使用时间信息来设置它们。
  • 对于其余的,未定义的行为是未定义的——任何事情都可能发生。有时,malloc() 返回的数据可能大多为零。
猜你喜欢
  • 1970-01-01
  • 2019-09-18
  • 2010-12-14
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 2011-01-21
相关资源
最近更新 更多