Nathan Lee
Nathan Lee

Reputation: 75

Memory allocation?

I have code that looks like the one below. It shows the current date and date after 100 days. However, I've noticed that result turns out to be same. So I thought maybe the addresses of structure or variable were same.

I put "%p" of variable now, later, lnow, and tnow and the result on the very bottom shows that structure pointer of lnow and tnow are both 02B51AA0 while variable later and now have different address. Now, if I move lnow = localtime(&later) into different location, after first switch statement, then address changes and it works perfectly. Could you explain why this happens?

#include <stdio.h>
#include <time.h>
struct tm* tnow;
struct tm* lnow;

int main(void) 
{
    time_t now = time(NULL);

    time_t later = now + 100*24*3600;
    printf("%p\t%p\n", &now, &later);
    lnow = localtime(&later);
    tnow = localtime(&now);
    printf("%p\t%p\n", lnow, tnow);
    printf("%d.%d.%d\t", tnow->tm_year+1900, tnow->tm_mon+1, tnow->tm_mday);
    switch (tnow->tm_wday)
    {
        case 0: puts("SUNDAY"); break;
        case 1: puts ("MONDAY"); break;
        case 2: puts("TUESDAY"); break;
        default: puts("ELSE"); break;
    }

    printf("%d.%d.%d\t", lnow->tm_year+1900, lnow->tm_mon+1, lnow->tm_mday);
    switch (lnow->tm_wday)
    {
        case 0: puts("SUNDAY"); break;
        case 1: puts ("MONDAY"); break;
        case 2: puts("TUESDAY"); break;
        default: puts("ELSE"); break;
    }

    return 0;
}

Results:

0061FF2C 0061FF28 
02B51AA0 02B51AA0
2017.12.8 ELSE
2017.12.8 ELSE

Upvotes: 1

Views: 83

Answers (2)

chux
chux

Reputation: 153338

The standard C library has 3 functions ctime(), gmtime(), localtime() that all use the same static struct tm object. A call to anyone of them or a repeated call, will re-use that same object.

The calls below return either NULL (if the conversion failed) or a pointer to the same object. The struct tm object may be over written each call.

Execution of any of the functions that return a pointer to one of these object types may overwrite the information in any object of the same type pointed to by the value returned from any previous call to any of them ... C11dr §7.27.3 1

struct tm *lnow = localtime(&later);
struct tm *tnow = localtime(&now);
struct tm *foo = gmtime(&now);

To retain the result, copy the object referenced by the returned pointer. Error checking is a good idea too.

struct tm *tm_ptr = localtime(&later);
if (tm_ptr == NULL) {
  fprintf(stderr, "Bad later time\n");
  exit(EXIT_FAILURE);
}
struct tm lnow = *tm_ptr;  // copy the broken-down time
switch (lnow.tm_wday) 
  ...

Upvotes: 0

John3136
John3136

Reputation: 29266

  1. Why are you printing the address of now and later ? These are just time_t values so the address is useless.
  2. localtime returns a pointer to an internal buffer - the same each time, so you need to copy the values out of it if you want to do localtime on a second time.

Upvotes: 3

Related Questions