异常程序终止时的访问冲突(C ++)

时间:2011-06-10 09:19:36

标签: c++ access-violation

以下最小代码示例在正常终止时(通过按Enter键)运行正常:

#include <stdio.h>
#include <iostream>
#include <string>

using namespace std;

class SingletonLogClass
{

private:

    SingletonLogClass() {}

public:

    ~SingletonLogClass()
    {
        LogMessage("~SingletonLogClass()");
    }

    static SingletonLogClass& getInstance(void)
    {
        static SingletonLogClass inst;
        return inst;
    }

    void LogMessage(string msg)
    {
        //printf("%s\n", msg.c_str());
        cout << msg << endl;
    }

};

int main(int argc, char* argv[])
{
    SingletonLogClass::getInstance().LogMessage("This is a message");
    getchar();
    return 0;
}

当我通过关闭控制台窗口终止程序时,它取决于LogMessage函数的实现。如果使用printf实现,一切都很好。但是当使用cout实现时,我会收到访问冲突。

有人可以解释一下吗? 通过关闭控制台窗口终止程序时到底发生了什么? 为什么它适用于printf但不适用于cout

我正在使用VC ++ 2010。

1 个答案:

答案 0 :(得分:6)

cout是一个全局对象。您的单例实例(在getInstance静态成员函数中定义为static)也是一个全局对象。

在C ++中,您无法控制构造顺序,也无法控制全局对象的破坏。因此,cout对象可能会在SingletonLogClass之前被破坏。由于SingletonLogClass的析构函数会记录某些内容,因此不再使用cout(而printf可以正常使用)。

当程序正常终止(按下回车)并因此退出main函数时,以及当程序通过关闭shell突然终止时的行为差异来自破坏全局变量的顺序。 您无法控制全局对象的销毁顺序。