0

次のコードを使用して、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;
}

私が知らなかったのは、 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できるはずの null ポインターが返されます。アサーション エラーはおそらく、ヒープが破損していることを示しています。これは、プログラム内の何かが何か悪いことをしたことを意味します。おそらく、割り当てていないメモリを解放したり、バインドされた配列を超えて書き込んだり、システムが追跡するために使用する情報を破壊したりしています。もの。

<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) を取得した場合、これはほとんどの場合、他の関数が new/malloc で割り当てられていないブロックで free を呼び出したか、何かが上書きされていることを意味します。割り当てられたブロックのバッファの最後。もう 1 つの可能性は、同様の方法で表示される「解放後に使用」です。

時間関数を呼び出す前に何が起こるかに集中します。それは単純なものである可能性が非常に高く、特定のタイプのヒープ破損の悪意にすぎず、かなり後になるまで発見されません。

于 2013-08-17T22:52:17.280 に答える