写入未打开的std :: ofstream

时间:2015-03-05 06:03:02

标签: c++

我最近写了一些我认为没问题的代码,但是一位同事说它在我们的应用程序中导致了随机崩溃。违规代码正在写入未打开的流。我的问题是:是否可以写入尚未打开的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;
};

我的同事说他通过将所有输出操作包装到m_debug_log并对其进行有效性检查来阻止随机崩溃。因此,仅当m_debug_log是有效输出流时才执行输出操作。

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

当然,只有在有效时写入流才是最有意义的。但我从没想过写入未打开的游戏会导致正确性问题。 (是的,这是低效的,但编码速度是我当时的最高优先级。)

我很快就搜索过,但没有发现任何明确的事情。特别是在写入未初始化的流时,我没有看到任何关于未定义行为的明确说明。初始实施是否应该是正确的?我的问题是一般问题,而不是特定的实施问题。为了我的价值,我经常使用VS 2010,VS 2013,Ubuntu 12.04和Centos 6.3,并发现初始测试没有问题。只有当碰撞发生时才运行较长时间。

1 个答案:

答案 0 :(得分:2)

只要有任何内容写入,默认构造(未打开)std::ofstream就会变为bad。后续写入应该静默(并且安全!)失败。

除非微软的实施特殊,否则我怀疑随机崩溃来自其他地方。确保m_debug_log完全构造,即使只使用默认构造函数。您确定真正的DoSomething不是静态方法吗?