Почему difftime () приводит к разным результатам при использовании указателя mktime и не указателя?

Я пытаюсь использовать

    difftime(time_t end, time_t mktime(start) )

рассчитать разницу между двумя разными временами двумя разными способами. Просто ради любопытства. И я обнаружил, что это приводит к разным результатам, неудачам и успехам. Я не знаю, почему это произошло?

Почему это приводит к различным результатам в двух случаях следующим образом?

    // Failure Case 1     when execution, segmentation fault
time_t end;
time(&end);

struct tm * start;   // defining a pointer

start->tm_hour = 0;
start->tm_min  = 0;
start->tm_sec  = 0;
start->tm_year = 114;
start->tm_mon  = 6;
start->tm_mday = 29;

double second = difftime(end, mktime(start) ); // where problem come from!

// Success Case 2, with expected result
time_t end;
time(&end);

struct tm start;   // defining a non-pointer

start.tm_hour = 0;
start.tm_min  = 0;
start.tm_sec  = 0;
start.tm_year = 114;
start.tm_mon  = 6;
start.tm_mday = 29;

double second = difftime(end, mktime( &start) );

-1

Решение

Исходный случай 1 не выделяет память, и оба случая не очищают ВСЕ поля в tm структура, которая может потребоваться для получения правильного результата (и, безусловно, является «хорошей практикой»).

Чтобы решить Случай 1 в C, лучшее решение состоит в том, чтобы использовать calloc:

struct tm *start = calloc(1, sizeof(struct tm));

start->tm_year = 114;
start->tm_mon  = 6;
start->tm_mday = 29;

а потом, когда вам больше не нужен start ценность, использование

free(start);

(Обратите внимание, что поскольку структура заполнена нулями, вам больше не нужно вручную устанавливать часы, минуты, секунды)

В C ++ вы бы использовали new вместо:

tm *start = new tm();
...
// After it is finished.
delete start

Пустая скобка в tm() делает его «заполненным нулевыми значениями» после выделения фактической памяти.

Вариант «Случай 2» является предпочтительным, поскольку он выделяет start переменная в стеке.

Случай 1 несколько плох, так как выделение памяти для небольших структур данных (маленький обычно означает что-то меньше, чем около 1 КБ, но это зависит от фактической среды выполнения, часы с 64 КБ ОЗУ могут иметь более строгие требования, чем настольный компьютер с 16 ГБ ОЗУ и мобильный телефон будет где-то посередине, в зависимости от того, что это за телефон). Есть по крайней мере две причины, чтобы избежать «маленьких» распределений памяти:

  1. Это занимает больше памяти, поскольку все известные распределители используют НЕКОТОРЫЕ дополнительные ресурсы памяти, чтобы отслеживать фактический «кусок» выделенной памяти.
  2. Это занимает дополнительное время, потому что new или же calloc намного сложнее, чем выделение в стеке (на типичных машинах выделение пространства в стеке занимает 1-2 инструкции выше и выше той же функции без переменных вообще, где вызов new или же {c,m}alloc может быть полдюжины только для вызова и то же самое снова для delete или же freeи от нескольких десятков до нескольких тысяч инструкций внутри этих библиотечных функций — сколько времени занимает код, во многом зависит от того, как он реализован, и от того, имеется ли во время выполнения некоторая «доступная память», или требуется вызов в ОС, чтобы «получить еще немного» память «так же). И, конечно же, вам нужно следить за распределением, а не «просачивать» его. [Для этого тоже есть решения на C ++, но я уже написал достаточно в этом ответе, чтобы было трудно следовать]

Для случая 2 вы можете использовать:

struct tm start = {};

(И опять же, вам не нужно устанавливать нулевые значения для часа, минуты и секунды)

В C ++ правильно опускать struct, поскольку struct tm { ... }; объявление в соответствующем заголовочном файле делает имя tm представлять структуру в любом случае — это относится ко всем struct а также class Исключением являются только имена, если одно и то же имя используется по-другому, например, есть функция или переменная с именем tm в том же контексте — в этом случае компилятор выдаст сообщение об ошибке «не понимаю, что вы подразумеваете под tm здесь «[точная формулировка зависит от того, какой компилятор используется].

Так как оригинальный вопрос определяет ОБА C и C ++, я попытался объяснить

3

Другие решения


По вопросам рекламы [email protected]