使用mktime处理指针和非指针时,为什么difftime()会导致不同的结果?

时间:2014-07-30 23:07:39

标签: 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 个答案:

答案 0 :(得分:3)

原始案例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()中的空括号在分配实际内存后使其“填充零值”。

首选“Case 2”变体,因为它在堆栈上分配start变量。

案例1有些不好,因为为小型数据结构分配内存(小的通常意味着小于1KB左右,但它取决于实际的运行时环境,具有64KB RAM的手表可能比具有更大的台式机具有更严格的要求16GB的RAM和一部手机将介于两者之间,这取决于它是什么类型的手机)。避免“小”内存分配至少有两个原因:

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

    struct tm start = {}; 
    

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

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

    由于原始问题指定BOTH C和C ++,我试图解释