我尝试使用
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) );
答案 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和一部手机将介于两者之间,这取决于它是什么类型的手机)。避免“小”内存分配至少有两个原因:
new
或calloc
比堆栈上的分配复杂得多(在典型的机器中,在堆栈上分配空间需要1-2个指令,超出相同的功能完全没有变量,只有呼叫new
或{c,m}alloc
的呼叫可以是半打,而delete
或free
的呼叫再次相同,几十个这些库函数中的几千个指令 - 代码的长度在很大程度上取决于它是如何实现的,以及运行时是否有一些“可用内存”或者需要调用操作系统以“获得更多内存” )。当然,您需要跟踪分配而不是“泄漏”它。 [也有C ++解决方案可以做到这一点,但我已经在这个答案中写得足以让它难以理解] 对于案例2,您可以使用:
struct tm start = {};
(同样,您不需要为小时,分钟和秒设置零值)
在C ++中省略struct
是正确的,因为相关头文件中的struct tm { ... };
声明使得名称tm
无论如何都代表了结构 - 这适用于所有struct
和class
名称 - 唯一的例外是如果以不同的方式使用相同的名称,例如在同一个上下文中有一个名为tm
的函数或变量 - 在这种情况下,编译器会给出一些错误,说“不明白你的意思tm
”[确切的措辞因编译器而异使用]。
由于原始问题指定BOTH C和C ++,我试图解释