Pregunta

Aquí está mi situación actual:

  • Tengo dos estructuras tm, tanto en conjunto a la hora actual
  • I hacer un cambio a la hora en una de las estructuras
  • El cambio se está produciendo en el otro struct mágicamente ....
  • ¿Cómo puedo evitar que esto ocurra? Tengo que ser capaz de comparar y saber el número de segundos entre dos momentos diferentes - la hora actual y una vez en el futuro. He estado usando difftime y mktime para determinar esto. Reconozco que no necesito técnicamente dos estructuras tm (la otra estructura podría ser sólo un time_t cargan con el tiempo prima), pero todavía estoy interesado en la comprensión de por qué ocurre esto.

vacío rastreador :: monitor (char * buffer) {

// 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;
}
¿Fue útil?

Solución

Hay que hacer esto:

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

De esta manera se mantendrá una copia local de la estructura tm. Esta estructura se asigna internamente en la biblioteca estándar, cada llamada a localtime apuntará a la misma dirección de memoria!

Otros consejos

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

  

Esta estructura se reserva estáticamente y compartido por las funciones gmtime y hora local. Cada vez que una de estas funciones se llama el contenido de esta estructura se sobrescribe.

Tendrá que copiar el valor de la estructura. Sus funciones pueden devolver un struct tm por valor, se podría eliminar la referencia de las funciones en el programa principal, etc.

En realidad no tiene dos estructuras diferentes tm en absoluto. Lo que tenemos es dos punteros estructura tm, ambos apuntando en la misma estructura estática devuelto por localtime. Así pues, parece que los cambios en uno afectan al otro, pero en realidad es simplemente una estructura cuenta con dos punteros diferentes a él.

La forma más segura de resolver esto es no depender de la estructura estática de localtime, pero el uso localtime_r que obligue a pasar en su propio puntero estructura tm, que luego será llenada. Por ejemplo:

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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top