2

A std::vector contains a buffer of continuous memory internally for a given type, with the exception of bools. Is there anyway of constructing a vector by specifying this buffer such that no coping of data is required?

I have a C api which gives me a buffer of data of a certain type. I would like to be able to manipulate this data via the functionality associated with std::vector, such as std::vector<>::iterator, begin(), end() etc.

Maybe you have a better suggestion as to how I might work with these buffers, as they are huge and I don't wish to copy them.

The api allocates the memory and provides a function which I call to tell it to release it again.

4
  • 3
    Maybe you're not aware of it, but pointers are iterators. Commented Aug 10, 2012 at 8:52
  • 1
    Do you provide the buffer to the C API to fill in, or does it allocate the memory for it and return that to you? Commented Aug 10, 2012 at 9:03
  • @JohnB It allocates the memory and provides a function which I call to tell it to release it again. Commented Aug 10, 2012 at 9:10
  • Ok so you can't make a vector and give it the memory from that then. Was just a thought Commented Aug 10, 2012 at 9:22

1 Answer 1

4

Why dont you just wrap the buffer in a simple class containing the functions you want to be able to use. Something like this will probably suffice, using the fact that pointers are iterators.

template<typename T> struct RawBuffer<T> { RawBuffer( T* in_buffer, size_t in_n ) : buffer(in_buffer), n(in_n) {} T* buffer; size_t n; T* begin() { return buffer; } T* end() { return buffer+n; } const T* begin() const { return buffer; } cont T* end() const { return buffer+n; } T& operator[](size_t i) { return buffer[i]; } const T& operator[](size_t i) const { return buffer[i]; } }; 

Now you can use it kinda like a vector:

RawBuffer<MyObject> values( generate_objects(n), n ); //Set an entry values[1] = MyObject() //Or use an entry values[1].do_something(); //Lets use some std functions on the object. std::for_each( values.begin(), values.end(), my_object_fn ); //Or create a real vector from it std::vector<MyObject> values_copy( values.begin(), values.end() ); 

If you also want to manage the memory that the buffer contains then you'll need to add a destrtuctor and remove the default copy constructor and assignment operator.

Sign up to request clarification or add additional context in comments.

3 Comments

And the reson to wrap this is... ? He might aswell just use buffer[i], &buffer[0]` and &buffer[0] + n directly.
@Xeo - while I agree that often just using the buffer directly will be appropriate there are many reasons not to. There may be other members of vector he wants that aren't so simple to express using pure iterators. He might need to use the object in a templated method expecting certain member functions. He might not want to keep track of n separately from the buffer. You might want to ensure it is disposed of correctly.
This exactly what I would do only written better than my answer which I'll remove in a bit to avoid duplication with no additional information... You could also use the class to handle the lifetime of the data through a destructor that frees it too, giving another good reason to do this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.