-1

最近、Visual C++ 2010 で非常に単純なロガー クラスをプログラミングしていますが、問題があります。プログラムを実行するたびに、デバッグ アサーション エラーが表示されます。

Expression: _CrtIsValidHeapPointer(pUserData)

これは私のクラスがどのように見えるかです (基本的に、ここの回答から少し変更されただけですC++ Singleton design pattern ):

class Logger
{
public:
    // Returns static instance of Logger.
    static Logger& getInstance()
    {
        static Logger logger; // This is where the assertion raises.
        return logger;
    }

    void logError(std::string errorText);

    // Destructor.
    ~Logger();

private:
    std::ofstream logFileStream;

    // The constructor is private to prevent class instantiating.
    Logger();
    // The copy constructor and '=' operator need to be disabled.
    Logger(Logger const&) { };
    Logger& operator=(Logger other) { };
};

コンストラクターは次のとおりです。

Logger::Logger()
    : logFileStream(Globals::logFileName, std::ios_base::trunc)
{
    // (Tries to open the file specified in Globals for (re)writing.)
}

静的変数やメソッドを使えばなんとか解決できることはわかったのですが、このコードのどこが悪いのかわかりません。問題がどこにあるか、誰か知っていますか?

編集:参考までに、このコードが呼び出されたときに失敗が発生します(初めて):

Logger::getInstance().logError("hello");

EDIT 2:logFileNameこれはinの定義ですGlobals:

static const std::string logFileName = "errorLog.log";
4

2 に答える 2

1

私の推測では、別のグローバル変数のコンストラクターから呼び出しており、悪名高い初期化順序の大失敗に遭遇しています。他の翻訳単位のグローバルの前に初期化されているgetInstance()かどうかは不明です。Globals::logFileName

1 つの修正方法は、グローバル コンストラクターが呼び出される前に静的に初期化される古い学校の C 文字列を使用することです。

static const char * logFileName = "errorLog.log";

別の可能性は、関数を介してアクセスすることです。

static std::string logFileName() {return "errorLog.log";}

私の好みの解決策は、グローバルインスタンスを完全に削除し、必要なものへの参照を渡すことです。しかし、特にグローバルを使用するコードがすでに大量にある場合は、かなり面倒だと感じる人もいるでしょう。

于 2012-06-22T12:07:42.203 に答える
0

C++/CLI は標準の C++ ではなく、わずかに異なるルールで機能します。C++/CLI マネージド コードを使用していますか? (/clr コンパイラ オプション?) これは、C++ (アンマネージ) コードと C++/CLI (マネージ) コードを混在させる場合によくある問題のようです。これは、プログラムの初期化とプログラムの終了時にマネージドおよびアンマネージドの構築と破棄が発生する方法に関係しています。デストラクタの削除は私にとってはうまくいきます - あなたの Logger クラスでそれを行うことができますか?

詳細と考えられる回避策については、次を参照してください。

http://www.codeproject.com/Articles/442784/Best-gotchas-of-Cplusplus-CLI

http://social.msdn.microsoft.com/Forums/vstudio/en-US/fa0e9340-619a-4b07-a86b-894358d415f6/crtisvalidheappointer-fails-on-globally-created-object-within-a-static-library?フォーラム=vcgeneral

http://forums.codeguru.com/showthread.php?534537-Memory-leaks-when-mixing-managed-amp-native-code&p=2105565

于 2014-05-27T21:28:51.570 に答える