替代C / C ++ localtime()

时间:2013-08-17 20:43:11

标签: c++ windows visual-studio c++11

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

time_t rawtime;
struct tm * timeinfo;

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

不幸的是,当使用消息_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)调用localtime(__getgmtimebuf - > _malloc_crt中的某个地方)时,我收到“debug assertion failed”。

我错过了什么,我是否需要一些编译标志(我使用vs 2012与c ++ 11)?

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


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

我在做的事情是这样的:

#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 ThompsonMats Petersson的两个怀疑都是基础和正确的,因此我会将Keith的答案标记为正确,因为它是解决这个模糊错误的第一个良好导致,即使我最初没有提供足够的信息

谢谢

2 个答案:

答案 0 :(得分:5)

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应该能够处理。断言错误可能表明堆已损坏 - 这意味着程序中的其他已经做了一些坏事,可能释放了你没有分配的内存或者写过数组绑定和破坏信息系统用来跟踪事物。

<ctime>切换到<chrono>本身可能是一个好主意,但它不是您问题的解决方案。您需要跟踪并更正程序正在执行的任何破坏堆的操作。

更新:

由于解决方案应该在答案中,而不是在问题中,我在这里复制这个问题:

  

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

     

<强> SOLUTION:

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

来自Keith ThompsonMats Petersson的怀疑都是   接地并且正确,所以我会将Keith的答案标记为正确   即使我没有解决这个模糊错误的第一个良好的领导   最初提供足够的信息。

答案 1 :(得分:1)

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

我会专注于你在调用时间函数之前发生的事情。它很可能是一件简单的事情 - 它只是某些类型的堆损坏的狡猾,你很快就会发现它。