写入未打开的 std::ofstream

Phi*_*hil 5 c++

我最近写了一些我认为还可以的代码,但一位同事说它导致我们的应用程序随机崩溃。违规代码正在写入未打开的 ofstream。我的问题是:写入尚未打开的 ofstream 是否可以?当一个类的初始化不会打开它的 ofstream 来记录调试信息时,就会出现这种情况。但是后续的方法仍然会使用未打开的 ofstream。下面是一个例子:

class A {
  public:
    A(const std::string& fname) {
        if (!fname.empty()) {
            m_debug_log.open(fname.c_str());
        }
    }

    void DoSomething() {
        m_debug_log << "doing something useful now" << std::endl;
    }

  private:
    std::ofstream m_debug_log;
};
Run Code Online (Sandbox Code Playgroud)

我的同事说他通过m_debug_log对 ofstream 进行有效性检查来包装所有输出操作来阻止随机崩溃。因此输出操作仅在m_debug_log有效输出流时执行。

    void DoSomething() {
        if (m_debug_log)
            m_debug_log << "doing something useful now" << std::endl;
    }
Run Code Online (Sandbox Code Playgroud)

当然,只有在流有效时才写入流最有意义。但我从没想过写入未打开的 ofstream 会导致正确性问题。(是的,它效率低下,但当时编码速度是我的首要任务。)

我迅速搜索,但没有找到任何确定的内容。特别是在写入未初始化的 ofstream 时,我没有看到任何关于未定义行为的明确信息。最初的实施应该是正确的吗?我的问题是一般性问题,而不是关于特定实现的问题。值得一提的是,我经常使用 VS 2010、VS 2013、Ubuntu 12.04 和 Centos 6.3,并且在初始测试中没有发现任何问题。只有在长时间运行时才会发生崩溃。

Bul*_*net 2

一旦向默认构造的(未打开的)写入任何内容,std::ofstream它就会变得很糟糕。后续写入应该默默地(并且安全地!)失败。

除非微软的实施很特殊,否则我怀疑随机崩溃来自其他地方。确保 已m_debug_log完全构造,即使仅使用默认构造函数也是如此。你确定 realDoSomething不是静态方法吗?