cdatemallocmktimetime.h

Strange behavior of mktime() when using passing parameter created by malloc


Below I have four functions.
first() and second() initialize only the year, mon & mday of structure tm.
first_p() and second_p allocate memory using malloc, then assign year, mon & mday.
All functions call mktime() at the end.

#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));
}

I tried different permutation when calling these functions in main():

1) first_p() and second_p() show random date and time.

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) only second_p() shows random date and time.

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) Only second_p() shows random date and time.

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() and second_p() show random date and time.

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

What I observe is:

Am I missing something about mktime() that's responsible for this behavior?

Edit:
I added free(date1); and free(date2); at the end of first_p() and second_p(). Now calling *_p() functions one after another doesn't display random date and time. However calling first() or second() function before them shows random date and time for the first *_p() function while the functions the come after it doesn't, i.e, for cases 1) , 3) and 4) listed above.

However, can't free it as I need them somewhere else (why I had to use malloc in the first place). Is there a way to achieve it?


Solution

  • You've got quasi-random (indeterminate) values in the hours, minutes, seconds and daylight saving flag in the malloc() data, so you get indeterminate results back from mktime().

    Use calloc() instead of malloc(), or zero the fields yourself.

    Also, consider setting the tm_isdst member to -1 to let the system determine whether daylight saving or standard time was appropriate for the dates.