2017-10-25 7 views
0

出力をstdoutまたはファイルにするコードを記述しています。これを行うには、ostreamを使用すると便利です。私はそれを適切に使用しないようです。ここには最小限の例があります。ostreamを参照として渡しているSegfault

#include <fstream> 

struct A { 
    std::ostream *os; 

    A (const char *fn) { 
    std::filebuf fb; 
    fb.open (fn, std::ios::out); 
    os = new std::ostream(&fb); 
    } 

    std::ostream &getOS() { 
    return *os; 
    } 
}; 

int main(int argc, char **argv) { 
    A a("foo.txt"); 
    a.getOS() << "bar" << std::endl; 
    return 0; 
} 

コードはコンパイルされますが、実行時にセグメンテーションフォルトが発生します。 ValgrindはUse of uninitialised value of size 8と言っていますが、正しく解釈することはできません。同様に、gdbは違反行(a.getOS()への呼び出し)を返しますが、修正方法はわかりません。

+4

あなたのfilebuf fbは、コンストラクタが終了するとスコープを使い果たします。 ostreamは破壊されたオブジェクトへのポインタを保持します。 – Jodocus

答えて

4

@ Jodocusがコメントしたように、変数std :: filebuf fbはコンストラクタ内でローカルです。それは範囲外になると破壊されます。この問題は、std :: filebuf fbをメンバー変数として定義することで修正できます。

#include <fstream> 

struct A 
{ 
    std::ostream *os; 
    std::filebuf fb; 

    A (const char *fn) 
    {  
     fb.open (fn, std::ios::out); 
     os = new std::ostream(&fb); 
    } 

    std::ostream &getOS() 
    { 
     return *os; 
    } 
}; 

int main(int argc, char **argv) 
{ 
    A a("/home/test.txt"); 
    a.getOS() << "bar" << std::endl; 
    return 0; 
} 
関連する問題