0

我正在尝试使用以下代码在 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;
}

我不知道的是 B 的析构函数在连接之前和线程完成工作之前被调用。

解决方案:

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

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

谢谢

4

2 回答 2

4

有其他选择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>本身可能是一个好主意,但这不是解决问题的方法。您需要追踪并纠正您的程序所做的任何破坏堆的操作。

更新 :

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

我不知道B的是,在加入之前和线程完成工作之前调用了析构函数。

解决方案:

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

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

于 2013-08-17T21:13:54.693 回答
1

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

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

于 2013-08-17T22:52:17.280 回答