c++ - 为什么使用 mktime 处理指针和非指针时 difftime() 会产生不同的结果?

标签 c++ c mktime time.h

我尝试使用

    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 不分配内存,并且两种情况都没有清除 tm 结构中的所有字段,这可能需要获得正确的结果(当然是一个“好的结果”)实践”)。

要解决C语言中的情况1,最好的解决方案是使用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有点糟糕,因为为小数据结构分配内存(小通常意味着小于1KB左右的任何东西,但这取决于实际的运行环境,具有64KB RAM的 watch 可能比具有64KB RAM的台式机有更严格的要求16GB RAM,手机则介于两者之间,具体取决于手机的类型)。避免“小”内存分配至少有两个原因:

  1. 它需要更多的内存,因为所有已知的分配器都使用一些额外的内存来跟踪分配的实际“ block ”内存。
  2. 需要额外的时间,因为newcalloc比堆栈上的分配复杂得多(在典型的机器中,在堆栈上分配空间需要1-2条指令上面和后面都是完全没有变量的相同函数,其中对 new{c,m}alloc 的调用可能只是为了调用而进行了六次,并且相同再次对于deletefree,以及这些库函数中的几十到几千条指令 - 代码的长度很大程度上取决于它是如何实现的,以及运行时是否有一些“可用内存”,或者还需要调用操作系统来“获取更多内存”)。当然,您需要跟踪分配情况而不是“泄漏”它。 [也有 C++ 解决方案可以做到这一点,但我已经在这个答案中写了足够多的内容,使其难以理解]

对于情况 2,您可以使用:

struct tm start = {}; 

(同样,您不需要为小时、分钟和秒设置零值)

在 C++ 中,省略 struct 是正确的,因为相关头文件中的 struct tm { ... }; 声明使名称为 tm 无论如何都表示结构 - 这适用于所有 structclass 名称 - 唯一的异常(exception)是相同的名称以不同的方式使用,例如在同一上下文中有一个名为 tm 的函数或变量 - 在这种情况下,编译器会给出一些错误,指出“不明白这里 tm 的意思”[确切的]措辞因使用的编译器而异]。

由于最初的问题指定了 C 和 C++,因此我尝试解释

关于c++ - 为什么使用 mktime 处理指针和非指针时 difftime() 会产生不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25048439/

相关文章:

c++ - 包装和使用返回带有 SWIG 结构的函数的问题(python)

python - 参数必须是 9 项序列,而不是 datetime.datetime

php - 如何在php中将日期和时间转换为时间戳?

c++ - LIBC 的 mktime 函数对相同的输入返回不同的值

c++ - 寻找具有 64 位支持和跨平台的 C++ 可嵌入脚本语言

c++ - 查找函数在内存中的地址

c++ - 灵活的数组作为类成员

c - 如果用户输入为0则退出程序

c - 使用 void 指针在 C 中重新编程 Calloc/Realloc

c - 二叉搜索树,节点删除崩溃