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

C++ 为什么difftime()在使用mktime处理指针和非指针时会产生不同的结果?,c++,c,mktime,time.h,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 * st

我试着用

    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:

当您不再需要开始值时,使用

free(start);
请注意,由于结构中填充了零,因此不再需要手动设置小时、分钟、秒

在C++中,你将使用新的替代:

tm中的空括号使其在分配实际内存后填充零值

case2变量是首选的,因为它在堆栈上分配start变量

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

它需要更多的内存,因为所有已知的分配器都使用一些额外的内存来跟踪实际分配的内存块。 这需要额外的时间,因为new或calloc比典型机器中堆栈上的分配要复杂得多,在堆栈上分配空间需要1-2条指令在同一个函数之上和之外,根本没有变量,其中对new或{c,m}alloc的调用可能只是调用一次,而对delete或free的调用可能是六次,这些库函数中包含几十到几千条指令——代码的长度在很大程度上取决于它是如何实现的,运行时是否有可用内存,或者是否需要调用操作系统来获得更多内存。当然,您需要跟踪分配情况,不要泄露。(也有C++解决方案,但是我已经写了足够的答案,让它很难跟上) 对于案例2,您可以使用:

struct tm start = {}; 
同样,您不需要为小时、分钟和秒设置零值

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


由于原始问题同时指定C和C++,我试图解释< /P> >您通过一个不确定的指针StuttTM开始,分配数据;正在调用未定义的行为。您忘记将内存分配给*start@TomásBadan在这种情况下如何分配内存?可以使用malloc:start=mallocsizeof*start;即使如此,由于tm结构中未初始化的字段,您可能会得到不同的结果。例如struct tm start={};结构字是C++中的opt,在C或TM*Stase= NeXTM中需要;[C++]或struct tm*start=calloc1,sizeoftm;[C] C++中的第二个变体是强优选的。尽可能避免新的。“那你就不能忘了删除。”马特斯皮尔森你的答案很清楚。非常感谢你。但是,无论哪种方式,变量start在第二行=difftimeend、mktime&start之后增加1小时;“我不知道为什么。”马特斯皮尔森我知道我的结果来自哪里。我从不给tm_isdst成员分配有意义的值。因此,mktime使用了一个不确定的值,其结果是未定义的行为。

tm *start = new tm(); 
...
// After it is finished. 
delete start
struct tm start = {};