破坏派生的std :: basic_ostream时的分段错误

时间:2016-11-09 16:22:26

标签: c++ c++11 segmentation-fault libc++

我从std::basic_ostream派生,因为我需要更改创建基础文件缓冲区的方式。 (我需要一个我可以查询的唯一文件名,以便文件在关闭时可以删除;即,不能使用std::tmpnamstd::tmpfile。)我已经尝试过在这(见下文),但我在破坏时遇到了分段错误。

导致分段错误的原因是什么?似乎我没有为文件缓冲区分配内存,或者我要删除它两次。

// Compile with
//      clang++ -std=c++14 -stdlib=libc++ main.cpp  -o tmpFile
//

#include <iostream>
#include <fstream>
#include <string>
#include <streambuf>

using namespace std;

template< class charT, class traits=char_traits<charT> >
class FILE_streambuf : public std::basic_streambuf<charT, traits> {
public:
    FILE_streambuf(std::string& filename)
    {
      filename = "chicken";
      buffer_ = fopen(filename.c_str(), "wx");

    }

    virtual ~FILE_streambuf(){
        fclose(this->buffer_);
    }
    FILE* buffer_;
};

template< class charT, class traits=char_traits<charT> >
class tmp_ofstream : public basic_ostream<charT, traits>{
public:
    tmp_ofstream()
    : filename_("")
    {
        try{
            this->rdbuf(new FILE_streambuf<charT, traits>(filename_));
        } catch (const std::exception& e){
            throw e;
        }
    }

    ~tmp_ofstream(){
        delete this->rdbuf();
        remove( filename_.c_str() );
    }
    std::string filename() { return this->filename_; };
    std::string filename_;
};

int main(){

    tmp_ofstream<char> tmpStream;
    cout << "tmpStream has filename: " << tmpStream.filename();

    cout << "\n-----------------------------------------\n";

    return 0;
}

1 个答案:

答案 0 :(得分:0)

作为Igor Tandetnik has noted,代码隐式调用std::basic_ostream的默认构造函数,它不应该存在。代码用libc ++编译,因为the latter provides这样的(受保护的)默认构造函数作为扩展:

basic_ostream() {}  // extension, intentially does not initialize

如果tmp_ofstream的构造函数调用std::basic_ostream的标准批准构造函数,则问题会消失:

tmp_ofstream()
: basic_ostream<charT, traits>(0) // Sic!
, filename_("")
{
    try{
        this->rdbuf(new FILE_streambuf<charT, traits>(filename_));
    } catch (const std::exception& e){
        throw e;
    }
}