我最近写了一些我认为没问题的代码,但是一位同事说它在我们的应用程序中导致了随机崩溃。违规代码正在写入未打开的流。我的问题是:是否可以写入尚未打开的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,并发现初始测试没有问题。只有当碰撞发生时才运行较长时间。
答案 0 :(得分:2)
只要有任何内容写入,默认构造(未打开)std::ofstream
就会变为bad。后续写入应该静默(并且安全!)失败。
除非微软的实施特殊,否则我怀疑随机崩溃来自其他地方。确保m_debug_log
完全构造,即使只使用默认构造函数。您确定真正的DoSomething
不是静态方法吗?