2017-10-25 4 views
0

출력이 stdout 또는 파일 인 코드를 작성했습니다. 그렇게하기 위해 ostream을 사용하는 것이 편리하다는 것을 알았습니다. 내가 적절하게 사용하지 않는 것 같습니다. 여기에 최소한의 예가 나와 있습니다.ogstream을 참조로 전달하는 동안 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; 
} 
관련 문제