替代 C/C++ localtime()

Posted

技术标签:

【中文标题】替代 C/C++ localtime()【英文标题】:Alternative to C/C++ localtime() 【发布时间】:2013-08-17 20:43:10 【问题描述】:

我正在尝试使用以下代码在 C++ 中获取当前本地时间:

time_t rawtime;
struct tm * timeinfo;

time (&rawtime);
timeinfo = localtime (&rawtime);

不幸的是,当我使用消息 _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 调用本地时间(在 __getgmtimebuf -> _malloc_crt 中的某个位置)时,我收到“调试断言失败”。

我是否遗漏了什么,是否需要一些编译标志(我使用的是带有 c++11 的 vs 2012)?

如果没有,我还有什么选择?


我无法发布整个代码,并且隔离更多上下文并不容易。 似乎错误不是来自时间函数,而是来自其余逻辑(因为它们在单独的项目中工作),我会尝试找出导致它的原因,但仍然,我觉得错误有点晦涩难懂。

我正在做的事情是这样的:

#include <iostream>
#include <chrono>
#include <ctime>
#include <string>
#include <thread>

class A

public:
    void time()
       
        //time_t rawtime;
        //struct tm * timeinfo;

        //time (&rawtime);
        //timeinfo = localtime (&rawtime);

        time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        std::cout << std::ctime(&now);
    
;

class B

public:
    void run(A *a)
           
        this->a = a;

        this->t = new std::thread(t_f, *this);
        this->t->join();
    

    ~B()
    
        delete t;
        delete a;
    

    friend void t_f(B &b);

private:
    A *a;
    std::thread *t;
;

void t_f(B &b)

    b.a->time();



int main()

    B b;
    b.run(new A());

    return 0;

What I didn't know 是 B 的析构函数在连接之前和线程完成工作之前被调用。

解决方案:

时间函数(无论来自 ctime 还是 chrono)按预期工作 通过指针或 std::ref 将 B 传递给 t_f()

Keith Thompson 和 Mats Petersson 的两个怀疑都是有根据的且正确的,因此我会将 Keith 的回答标记为正确,因为它是解决这个晦涩错误的第一个好线索,即使我最初没有提供足够的信息。

谢谢

【问题讨论】:

C++11 中有全新的时间库 - &lt;chrono&gt;。但是你用的是VS2012,不知道对这个库的支持程度。 您可能需要检查time 调用是否实际成功,方法是检查它的返回值。如果调用失败,rawtime 的值未定义,可能是无效的时间戳 @DieterLücking 查看任何参考资料,例如this one. 对我来说没问题(VS2012 也是)。你能举一个完整的例子吗? 仔细阅读错误消息,您似乎在某处损坏了内存。您可能在代码中的某个地方有一个错误,您在某处写的东西超出(或低于)某些东西的范围。 【参考方案1】:

localtime 有其他选择,但这不是您应该关注的重点。

我把你的代码复制到了一个小程序中:

#include <ctime>
#include <iostream>
int main(void) 
    time_t rawtime;
    struct tm * timeinfo;

    time (&rawtime);
    timeinfo = localtime (&rawtime);

    std::cout << "rawtime = " << rawtime << "\n";
    std::cout << "Welcome to " << 1900 + timeinfo->tm_year << "\n";

它编译并运行没有错误:

rawtime = 1376773717
Welcome to 2013

您收到的错误消息似乎表明存在内存分配问题。 localtime 函数很可能在内部使用 malloc。如果malloc 因为没有足够的可用内存而失败,它会返回一个空指针,localtime 应该能够处理。断言错误可能表明堆已损坏 - 这意味着您的程序中的 其他东西 做了一些坏事,可能释放了您未分配的内存或写入超出数组绑定和破坏信息系统用于跟踪事物。

&lt;ctime&gt; 切换到&lt;chrono&gt; 本身可能是一个好主意,但这并不是解决问题的方法。您需要追踪并纠正您的程序所做的任何破坏堆的操作。

更新:

由于解决方案应该在答案中,而不是在问题中,因此我在此处从问题中复制此内容:

What I didn't know是B的析构函数被调用 在加入之前和线程完成其工作之前。

解决方案:

时间函数(无论来自 ctime 还是 chrono)按预期工作 通过指针或 std::ref 将 B 传递给 t_f()

Keith Thompson 和 Mats Petersson 的两个怀疑都是 扎根且正确,因此我将基思的答案标记为正确 即使我没有解决这个模糊错误的第一个好线索 最初提供足够的信息。

【讨论】:

确实,有时它似乎在其他时候不起作用(ctime 和 chrono 函数)。 @user2704:这意味着您的程序中存在错误,并且它在您没有向我们展示的代码中。如果您可以将您的程序缩小到一个足够小的完整示例来展示错误,并更新您的问题以显示它,那么我们可能会提供帮助。否则我们只能告诉您“某处存在错误,您需要修复它”。 @user2704:当我写上一条评论时,我还没有看到你更新的问题。但是您需要复制并粘贴 exact 代码。您发布的内容无法编译;你有一个错字,time_str_2time_str2。当我解决这个问题时,你的程序对我有用。请更新您的问题,向我们展示该程序的作用;就目前而言,我不知道它是否适合你。 那么有人可以提供本地时间的替代方案吗?问题的标题完全具有误导性。 :( @PaulProgrammerNoob 您可能想发布一个新问题。对 6 年前已解决的问题发表评论不太可能为您提供有用的答案。在您的新问题中,请解释您为什么需要替代方案(即您需要 localtime 未提供的内容)。【参考方案2】:

当您收到“__getgmtimebuf -> _malloc_crt) 和消息 _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)”时,这几乎总是意味着某个 OTHER 函数在未分配 new/malloc 的块上调用了 free,或者某些东西正在覆盖已分配块的缓冲区的末尾。另一种可能是“释放后使用”,它可以以类似的方式出现。

我会专注于在您调用时间函数之前会发生什么。这很可能是一些简单的事情 - 只是某些类型的堆损坏的狡猾,直到很久以后才会发现。

【讨论】:

以上是关于替代 C/C++ localtime()的主要内容,如果未能解决你的问题,请参考以下文章

Linux C 中获取local日期和时间 time()&localtime()函数

localtime vs localtime_s 和适当的输入参数

C++11使用using定义别名(替代typedef)

C/C++ 时间知识总结

C/C++时间函数总结

将 Node.js+Socket.io 包装成 OSX 可执行文件的可靠方法? (或用作替代品的 C/C++/Objective-C 库)