bool3max
bool3max

Reputation: 2865

sleep() and time() not functioning as expected inside for loop

I'm trying to create an array of tm struct pointers, with each struct having a tm_sec value 2 seconds larger than the previous one.

#include <stdio.h>
#include <time.h>
#include <unistd.h> /* sleep() */

int main(signed int argc, char **argv) {
    struct tm *collection[5];

    for(struct tm **p = collection; p < collection + 5; p += 1) {
        sleep(2);
        const time_t timeNow = time(NULL);
        *p = gmtime(&timeNow);
    }

    for(struct tm **p = collection; p < collection + 5; p += 1) {
        if(p != collection + 4) {
            puts((**p).tm_sec == (**(p + 1)).tm_sec ? "equal" : "not equal");
        }

        puts(asctime(*p));
    }
}

Execution lasts around 10 seconds, which seems fine, but the resulting output is:

equal
Sat Jul 28 01:42:15 2018
equal
Sat Jul 28 01:42:15 2018    
equal
Sat Jul 28 01:42:15 2018    
equal
Sat Jul 28 01:42:15 2018    
Sat Jul 28 01:42:15 2018

Compiled with GCC 7.3.0 on linux64. Don't know what I'm doing wrong.

note: Initially I didn't have the first for loop sleep on the insertion of the first element, but I removed it here for simplicity's sake. It doesn't make a difference.

Upvotes: 1

Views: 86

Answers (1)

o11c
o11c

Reputation: 16046

From the man page:

POSIX.1-2001 says: "The asctime(), ctime(), gmtime(), and localtime() functions shall return values in one of two static objects: a broken-down time structure and an array of type char. Execution of any of the functions may overwrite the information returned in either of these objects by any of the other functions." This can occur in the glibc implementation.

For single-threaded programs, simply dereference the pointers:

#include <stdio.h>
#include <time.h>
#include <unistd.h> /* sleep() */

int main(signed int argc, char **argv) {
    struct tm collection[5];

    for (struct tm *p = collection; p < collection + 5; p++) {
        sleep(2);
        const time_t timeNow = time(NULL);
        *p = *gmtime(&timeNow);
    }

    for(struct tm *p = collection; p < collection + 5; p++) {
        if(p != collection + 4) {
            puts((*p).tm_sec == (*(p + 1)).tm_sec ? "equal" : "not equal");
        }

        puts(asctime(p));
    }
}

For multi-threaded programs, you'll need to use gmtime_r and asctime_r

Upvotes: 2

Related Questions