【问题标题】:C++ application crashes while instantiating an ofstream object.C++ 应用程序在实例化 ofstream 对象时崩溃。
【发布时间】:2010-11-18 12:12:09
【问题描述】:

我在运行 C++ 应用程序时遇到了一个非常烦人的问题。我在 Windows Xp 的 Interix 子系统上使用 pgcpp 编译器。我的问题基本上在这里描述:

我在头文件中有一个类定义。该头文件包含在一个源文件中。这个类有两个构造函数,主要用于实现一个记录器。第一个构造函数接受 ostream *out 作为参数,而第二个重载构造函数接受文件名和默认布尔值 false。第二个构造函数的目标是为我们传递的文件名获取一个流,并开始向它记录消息。构造函数中的代码如下:

MessageLogger::MessageLogger(std::ostream *out): p_out (out), p_ofstream (0)  
{  
    if (p_out)  
    {  
        (*p_out) << "Started logging messages" << endl;  
    }  
}  

MessageLogger::MessageLogger (char const *filename, bool append_to_file) : p_out (0),   p_ofstream (0)  
{  
    if (append_to_file)  
    {  
    p_ofstream = new std::ofstream (filename, ios::app);  
    }  
    else  
    {  
        p_ofstream = new std::ofstream (filename);  
    }  

    p_out = p_ofstream;  

    if (p_out)  
    {  
        (*p_out) << "Started logging messages" << endl;  
    }  
}  

其中p_out和p_ofstream的声明如下:

std::ostream *p_out;
std::ofstream *p_ofstream;
unsigned int p_indent_level;

上面提到的三个都是私人成员。 MessageLogger 类的实例化如下:

MessageLogger logger ("filename");

请注意 append_to_file 的默认值为 false。 PGDBG 也是行为不端。当控件位于p_ofstream = new std::ofstream (filename); 并且它进入一个随机位置然后应用程序崩溃时,我莫名其妙地能够介入。

另外,当我尝试在 PGDBG 中查看混合代码或反汇编代码时,调试器崩溃并显示以下消息:

jpgdbg parse: Newline must follow cmd in 'eleq "0" struct MessageLogger *Mes
sageLogger::MessageLogger(struct basic_ostream *out); (TranslatorGeneric.cpp
)
'
jpgdbg jpgdbgFileSelector processMsg: Warning unexpected msg token 5
jpgdbg parse: Newline must follow cmd in 'eleq "1" struct MessageLogger *Mes
sageLogger::MessageLogger(char *filename, unsigned char append_to_file); (Tr
anslatorGeneric.cpp)
'
jpgdbg jpgdbgFileSelector processMsg: Warning unexpected msg token 5

我无法在示例程序中重现这一点,我做了与上面完全相同的事情,但一切正常。有人可以解释发生了什么,如果有解决办法?

谢谢, 阿迪亚。

【问题讨论】:

  • 在您的代码中,append_to_file 没有默认值。
  • 您的问题是关于应用程序还是调试器?在这两种情况下:你到底在问什么?
  • 问题是关于失败的应用程序。调试器只是我认为应该分享的一个附加问题。 append_to_file 设置为 false。很抱歉我没有显示完整的代码。
  • 如果这有帮助:我莫名其妙地能够进入 p_ofstream = new std::ofstream (filename); 行我的调试器将我带到某个随机的地方(一直是同一个地方),然后再进入另一个地方。这似乎非常奇怪。编译完成后目标文件是否有可能以某种方式损坏?

标签: c++ ofstream interix pgi


【解决方案1】:

为什么要使用动态分配的 ofstream 实例?你为什么不做类似下面的事情......

class Logger
{
  public:
    Logger(ostream& str) : _str(str.rdbuf()) // use the buffer from the stream
    {
      _str << "writing to passed in buffer" << endl;
    }
    Logger(const char* fname, bool append = false) : _str(cout.rdbuf())
    {
      _file.open(fname, (append)? ios::out|ios::app : ios::out);
      if (_file.is_open())
        _str.rdbuf(&_file); // redirects to file, else remains on cout

      _str << "expected to be logging to: " << fname << endl;
    }

    // use as needed

  private:
    filebuf _file;
    ostream _str;
};

这样即使您的文件失败,您仍然可以将日志输出输出到 cout...

回到你的问题,HW_NEW 是做什么的?根据您提供的基本信息,真的很难说...

【讨论】:

  • 这是我正在尝试迁移到 Windows 的大型应用程序的一部分。所以我真的无法控制或选择如何做到这一点。我已经编辑了我的问题,以使事情变得更加清晰。非常感谢您的回复。你现在能看看它并告诉我为什么会失败吗?我正在谈论的示例代码也是使用 pgcpp 编译的,因此我认为这不是编译器问题。除非我错了?
  • 好的,回到开头,您是否正确构建了所有对象/库(即它们是否都使用了正确的标头等)?如果有使用相同头文件的不同版本编译的对象等,您可能会发生随机崩溃。作为第一步,我会清理并重新编译所有内容。完成后,确认这确实是发生崩溃的地方(使用启用调试的构建)。然后在调试器中试一下,上面的代码应该是没问题的,而且那里发生crash可能是巧合……
  • 我让一位同事构建了整个应用程序。同样的事情也发生在她身上。我们做了一个全新的构建。如果您看到可能发生的一些与 C++/编译器相关的故障,您能告诉我吗?或者这只是中间已经失败的事情——如果有可能的话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-01
  • 2010-09-08
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 2019-03-29
相关资源
最近更新 更多