重新分配时退出时的 segv std::clog

segv on exit when reassigning std::clog

以下程序在使用 g++ 退出后出现分段错误:

#include <iostream>                                                         
#include <fstream>                                                          

int                                                                         
main()                                                                      
    {                                                                       
    std::ofstream logfile( "logfile" ) ;                                    
    if( !logfile.is_open() )                                                
        {                                                                   
        std::cerr << "oops ofstream\n" ;                                    
        return -1 ;                                                         
        }                                                                   
    std::clog.flush() ;                                                     
    std::clog.rdbuf( logfile.rdbuf() ) ;                                    

    std::clog << "test output\n" ;                                          
    std::clog.flush() ;                                                     
    std::cerr << "all done\n" ;                                             

    return 0 ;                                                              
    }                                                                       

知道为什么吗?

std::clog 和朋友的生命周期由 std::ios_base::Init 类型的静态对象管理 (C++11 27.5.3.1.6 Class ios_base::Init)。当该对象被销毁时(在 main() returns 之后),它会执行以下操作来销毁 std::clog 和相关的 iostream 对象 (C++11 27.5.3.1.6/ 4 Class ios_base::Init):

calls cout.flush(), cerr.flush(), clog.flush(), wcout.flush(), wcerr.flush(), wclog.flush()

flush() 的调用将使用 clog 中的 rdbuf() 对象,并且由于之前传递给 cloglogfile.rdbuf() 已被销毁,您得到未定义的行为。