我尝试使用
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,手机则介于两者之间,具体取决于手机的类型)。避免“小”内存分配至少有两个原因:
- 它需要更多的内存,因为所有已知的分配器都使用一些额外的内存来跟踪分配的实际“ block ”内存。
- 需要额外的时间,因为
new
或calloc
比堆栈上的分配复杂得多(在典型的机器中,在堆栈上分配空间需要1-2条指令上面和后面都是完全没有变量的相同函数,其中对new
或{c,m}alloc
的调用可能只是为了调用而进行了六次,并且相同再次对于delete
或free
,以及这些库函数中的几十到几千条指令 - 代码的长度很大程度上取决于它是如何实现的,以及运行时是否有一些“可用内存”,或者还需要调用操作系统来“获取更多内存”)。当然,您需要跟踪分配情况而不是“泄漏”它。 [也有 C++ 解决方案可以做到这一点,但我已经在这个答案中写了足够多的内容,使其难以理解]
对于情况 2,您可以使用:
struct tm start = {};
(同样,您不需要为小时、分钟和秒设置零值)
在 C++ 中,省略 struct
是正确的,因为相关头文件中的 struct tm { ... };
声明使名称为 tm
无论如何都表示结构 - 这适用于所有 struct
和 class
名称 - 唯一的异常(exception)是相同的名称以不同的方式使用,例如在同一上下文中有一个名为 tm
的函数或变量 - 在这种情况下,编译器会给出一些错误,指出“不明白这里 tm
的意思”[确切的]措辞因使用的编译器而异]。
由于最初的问题指定了 C 和 C++,因此我尝试解释
关于c++ - 为什么使用 mktime 处理指针和非指针时 difftime() 会产生不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25048439/