2

这是我目前的情况:

  • 我有两个 tm 结构,都设置为当前时间
  • 我在其中一个结构中更改了小时
  • 这种变化神奇地发生在另一个结构中......
  • 如何防止这种情况发生?我需要能够比较并知道两个不同时间之间的秒数——当前时间和未来时间。我一直在使用 difftime 和 mktime 来确定这一点。我认识到我在技术上不需要两个 tm 结构(另一个结构可能只是加载了原始时间的 time_t),但我仍然有兴趣了解为什么会发生这种情况。

无效跟踪器::监视器(字符*缓冲区){

// time handling
time_t systemtime, scheduletime, currenttime;
struct tm * dispatchtime;
struct tm * uiuctime;
double remainingtime;


// let's get two structs operating with current time
dispatchtime = dispatchtime_tm();
uiuctime = uiuctime_tm();

// set the scheduled parameters
dispatchtime->tm_hour = 5;
dispatchtime->tm_min = 05;
dispatchtime->tm_sec = 14;

uiuctime->tm_hour = 0;

    // both of these will now print the same time! (0:05:14)
    // what's linking them??

// print the scheduled time
printf ("Current Time :  %2d:%02d:%02d\n", uiuctime->tm_hour, uiuctime->tm_min, uiuctime->tm_sec);
printf ("Scheduled Time :  %2d:%02d:%02d\n", dispatchtime->tm_hour, dispatchtime->tm_min, dispatchtime->tm_sec);

}

struct tm* Tracker::uiuctime_tm(){
    time_t uiucTime;
    struct tm *ts_uiuc;

    // give currentTime the current time
    time(&uiucTime);

    // change the time zone to UIUC
    putenv("TZ=CST6CDT");
    tzset();

    // get the localtime for the tz selected
    ts_uiuc = localtime(&uiucTime);

    // set back the current timezone
    unsetenv("TZ");
    tzset();

    // set back our results
    return ts_uiuc;
}

struct tm* Tracker::dispatchtime_tm(){
    time_t currentTime;
    struct tm *ts_dispatch;

    // give currentTime the current time
    time(&currentTime);

    // get the localtime for the tz selected
    ts_dispatch = localtime(&currentTime);

    // set back our results
    return ts_dispatch;
}
4

3 回答 3

3

http://www.cplusplus.com/reference/clibrary/ctime/localtime/

该结构由 gmtime 和 localtime 函数静态分配和共享。每次调用这些函数中的任何一个时,都会覆盖此结构的内容。

您需要将值从结构中复制出来。您的函数可以按值返回 tm 结构,您可以取消引用主程序中的函数等。

于 2010-06-15T16:26:48.363 回答
3

你必须这样做:

struct tm* temp_tm;
struct tm dispatchtime; // No longer a pointer
struct tm uiuctime;     // No longer a pointer

temp_tm = dispatchtime_tm();
dispatchtime = *temp_tm; // Member to member copy

temp_tm = uiuctime_tm();
uiuctime = *temp_tm; // Member to member copy

这样,您将保留tm结构的本地副本。这个结构是在标准库内部分配的,每次调用localtime都会指向同一个内存地址!

于 2010-06-15T16:31:16.667 回答
1

您实际上根本没有两个不同的 tm 结构。你所拥有的是两个 tm 结构指针,它们都指向本地时间返回的同一个静态结构。因此,看起来对一个的更改会影响另一个,但实际上它只是一个结构有两个不同的指针。

解决这个问题最安全的方法是不要依赖localtime's 的静态结构,而是使用localtime_r它需要你传入你自己的 tm 结构指针,然后将其填充。例如:

void Tracker::uiuctime_tm(struct tm* out){
    time_t uiucTime;

    // give currentTime the current time
    time(&uiucTime);

    // change the time zone to UIUC
    putenv("TZ=CST6CDT");
    tzset();

    // get the localtime for the tz selected, and set back the result into the output parameter.
    localtime_r(&uiucTime, out);

    // set back the current timezone
    unsetenv("TZ");
    tzset();
}

struct tm uiuctime;
uiuctime_tm(&uiuctime);
于 2010-06-15T16:51:21.127 回答