-1

我尝试使用

    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) );
4

1 回答 1

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()使其在分配实际内存后“填充零值”。

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

情况 1 有点糟糕,因为为小数据结构分配内存(小通常意味着小于 1KB 左右,但这取决于实际运行时环境,具有 64KB RAM 的手表可能比具有 16GB RAM 的台式机具有更严格的要求,而手机介于两者之间,这在某种程度上取决于它是什么类型的手机)。避免“小”内存分配至少有两个原因:

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

对于案例 2,您可以使用:

struct tm start = {}; 

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

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

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

于 2014-07-31T00:20:36.523 回答