2010-11-18 86 views
1

运行C++应用程序时,我有一个非常恼人的问题。我在Windows Xp的Interix子系统上使用了pgcpp编译器。我的问题基本上描述在这里:C++应用程序在实例化一个ofstream对象时崩溃。

我有一个头文件中的类定义。这个头文件包含在一个源文件中。这个类有两个构造函数,基本上用来实现一个记录器。第一个构造函数将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 

我不能重现这个在示例程序在那里我做了完全一样的如上所述,但一切正常。有人可以解释发生了什么,如果有解决这个问题?

谢谢, Aditya。

+0

在你的代码中,'append_to_file'没有默认值。 – 2010-11-18 12:20:53

+0

是关于应用程序或调试器的问题吗?在这两种情况下:你到底在问什么? – 2010-11-18 12:24:58

+0

问题是关于失败的应用程序。调试器只是我认为应该分享的一个附加问题。 append_to_file设置为false。对不起,我没有显示完整的代码。 – Aditya 2010-11-18 13:02:13

回答

0

为什么使用动态分配的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; 
}; 

即使你的文件失败,您仍然有日志输出要清点这样......

回到你的问题,HW_NEW做什么?用你提供的基本信息很难说...

+0

这是我尝试迁移到Windows的一个巨大应用程序的一部分。所以我实在无法控制或选择如何做到这一点。我编辑了我的问题,使事情略微清晰。非常感谢答复。你现在可以看看,并告诉我为什么这是失败的?我所说的示例代码也是使用pgcpp编译的,因此我不认为这是编译器问题。除非我错了? – Aditya 2010-11-18 13:05:27

+0

好吧,回到开始,你是否正确构建了所有的对象/库(即它们是否都使用了正确的头文件等)?如果使用相同头文件的不同版本编译对象,则可能会发生随机崩溃等。作为第一步,我将清理并重新编译所有内容。一旦完成,确认这确实是发生崩溃的地方(启用了调试版本)。然后在调试器中试试,上面的代码应该没问题,并且可能偶然发生崩溃...... – Nim 2010-11-18 13:36:20

+0

我有一个同事构建了这个整个应用程序。同样的事情发生在她身上。我们做了一个新的构建。你能告诉我,如果你看到一些C++ /编译器相关的故障可能发生?或者这仅仅是中间的东西 - 如果有这样的事情是可能的。 – Aditya 2010-11-18 14:13:08