Budric
Budric

Reputation: 3709

C++ stream to memory

how can I create std::ostream and std::istream objects to point to a piece of memory I allocated and manage (I don't want the stream to free my memory).

I was looking at using rdbuf()->pubsetbuf() to modify one of the other streams - say sstringstream. However I think streambuf used by stringstream will free the buffer afterwards?

Basically I'm trying to serialize some things to shared memory.

Thanks.

Upvotes: 8

Views: 11068

Answers (3)

Stephan Lachnit
Stephan Lachnit

Reputation: 13

A minimal memory buffer has to implement only the overflow function of std::streambuf and keep track of the pointers of the streambuf. This is done via setp and pbump.

You will also need to add an underlying memory buffer, but this can be done rather easy. cppreference.com has a good example of an implementation based on an std::array in the already mentioned page for the overflow function. While this is a good start to learn, you might want to have a memory buffer that can resize. You can try to implement it based on an std::vector (like I did here).

I ended up writing a memory buffer based on std::realloc to get the most performance while also giving me the possibility to hand the raw pointer over to C libaries. You can find my implementation here.

Upvotes: 1

Joachim
Joachim

Reputation: 971

#include <iostream>
#include <streambuf>

//...
size_t length = 100;
auto pBuf = new char[length]; // allocate memory

struct membuf: std::streambuf // derive because std::streambuf constructor is protected
{
   membuf(char* p, size_t size) 
   {
       setp( p, p + size); // set start end end pointers
   }
   size_t written() {return pptr()-pbase();} // how many bytes were really written?
};

membuf sbuf( pBuf, length ); // our buffer object
std::ostream out( &sbuf );   // stream using our buffer

out << 12345.654e10 << std::endl;
out.flush();

std::cout << "Nr of written bytes: " << sbuf.written() << std::endl;
std::cout << "Content: " << (char*)pBuf << std::endl;

//...
delete [] pBuf; // free memory 

Upvotes: 3

Judge Maygarden
Judge Maygarden

Reputation: 27613

Take a look at the bufferstream class in the Boost.Interprocess library:

The bufferstream classes offer iostream interface with direct formatting in a fixed size memory buffer with protection against buffer overflows.

Upvotes: 8

Related Questions