这个流缓冲区有什么问题?

What's wrong with this stream buffer?

本文关键字:什么 问题 缓冲区      更新时间:2023-10-16

我在这里overflow()有什么问题。当我打印oss.str()时,它打印的是"Hello, Wor"而不是"Hello, World"。我做错了什么?

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
class io_buffer : public std::streambuf
{
public:
    io_buffer(std::ostream& os, int buf_size = 4)
        : os_(os), buffer(buf_size)
    {
        os_.clear();
        char* beg = buffer.data();
        setp(beg, beg + buffer.size());
    }
    int_type overflow(int_type c)
    {
        if (os_ && !traits_type::eq_int_type(c, traits_type::eof()))
        {
            *pptr() = traits_type::to_char_type(c);
            pbump(1);
            if (flush())
            {
                setp(buffer.data(), buffer.data() + buffer.size());
                return c;
            } else
                return traits_type::eof();
        }
        return traits_type::not_eof(c);
    }
    bool flush()
    {
        return os_.write(pbase(), pptr() - pbase());
    }
    int sync()
    {
        return flush() ? 0 : -1;
    }
private:
    std::ostream& os_;
    std::vector<char> buffer;
};
int main()
{
    std::ostringstream oss;
    io_buffer buf(oss);
    std::ostream os(&buf);
    std::string str("Hello, World");
    os << str;
    std::cout << oss.str() << std::endl;
}

您还需要刷新一个std::vector(缓冲区),即:

int_type overflow(int_type c)
    {
        if (os_ && !traits_type::eq_int_type(c, traits_type::eof()))
        {
            *pptr() = traits_type::to_char_type(c);
            pbump(1);
            if (flush())
            {
                buffer.clear();  // <-
                setp(buffer.data(), buffer.data() + buffer.size());
                return c;
            } else
                return traits_type::eof();
        }
        return traits_type::not_eof(c);
    }

更好的是,0x499602D2地址建议使用pbump(-buffer.size())以避免多次调用overflow()

问题是你使用:

setp(beg, beg + buffer.size());

在 overflow() 中,您添加了没有重新分配的新元素,结束指针应该是可访问的(如果您不想重新分配),否则您需要在 overflow() 中重新分配缓冲区。因此,请将其更改为:

setp(beg, beg + buffer.size() - 1);

在io_buffer构造函数

后来在溢出中将设置更改为:

pbump(-(pptr() - pbase()));

还要刷新缓冲区,请添加 endl:

os << str << endl;

工作示例:http://coliru.stacked-crooked.com/a/7c72ecfe78bb2aee