为什么将wcout / wcerr重定向到/ dev / null会导致程序崩溃?

时间:2013-01-15 21:38:01

标签: c++ redirect wofstream

考虑我的日志记录类

void LogWriter::InitLogWriter(void)
{
    wcout.flush();
    wcerr.flush();
    COUT_BACKUP = wcout.rdbuf(); // save original cout buffer
    CERR_BACKUP = wcerr.rdbuf(); //save original cerr buffer
    FileStreamOpen = false;
    switch(m_nTraceLvl)
    {
    case OffLevel:
        StopOutput();
        break;
    case ErrorLevel:
        OutputErrorsToFile(s_TraceFile);
        break;
    case DetailLevel:
        OutputAllToFile(s_TraceFile);
        break;
    default:
        StopOutput();
        break;
    }
    wcout << "Initialize Log Writer" << endl;
}
void LogWriter::OutputAllToFile(TCHAR* fileName)
{
    wstreambuf* fb = GetFileBufferStream(fileName);

    wcout.rdbuf(fb); // push wcout buffer to file
    wcerr.rdbuf(fb); // push cerr buffer to file

    FileStreamOpen = true;
}
void LogWriter::OutputErrorsToFile(TCHAR* fileName)
{
    wstreambuf* fb = GetFileBufferStream(fileName);
    wcerr.rdbuf(fb);
    FileStreamOpen = true;
    wofstream fout("/dev/null");
    wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'
}
void LogWriter::StopOutput(void)
{
    wofstream fout("/dev/null");

    wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'
    wcerr.rdbuf(fout.rdbuf()); // redirect cerr to fout
}
wstreambuf* LogWriter::GetFileBufferStream(TCHAR* fileName)
{
    filestr.open(fileName);
    return filestr.rdbuf();   // get file's streambuf
}
void LogWriter::Dispose()
{
    wcout << "Kill Log Writer" << endl;
    wcout.rdbuf(COUT_BACKUP); // restore the original stream buffer
    wcerr.rdbuf(CERR_BACKUP);

    if(FileStreamOpen)
    {
        filestr.close();
    }
}

现在,如果我将Tracing设置为DetailLevel(2),那么一切都很好。我的所有日​​志都会转到该文件。但是,如果我选择OffLevel或ErrorLevel我的程序崩溃..我的调试器没有打开所以我添加了cout&lt;&lt; “”在每一行(我讨厌这样做,但它有效),它指向我

wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'

作为我的罪魁祸首......我转向重定向wcout,首先重定向wcerr并且它有效(但是还没有调用wcerr)

这是我的问题?我应该首先处理wcout吗?我先试着冲洗......但是没用。所以我不知道。我做错了什么?

另外作为奖励..在我关闭LogWriter之前,为什么我的所有输出都没有进入文件? IE LogWriter :: Dispose()

1 个答案:

答案 0 :(得分:4)

您崩溃是因为在堆栈上创建了wofstream fout("/dev/null");并在您退出该函数后立即销毁。

将“/ dev / null”视为对待文件。也就是说,在OutputErrorsToFile("/dev/null")内拨打StopOutput()。实际上你甚至不需要/ dev / null,只需使用wcout.rdbuf(NULL),也应该更快。

要立即写入文件,请调用flush或使用std :: flush manipilator。