Mapping a vector<T> to a memory block...

B

barcaroller

I have a pointer to a memory block. Is there a way I can map a vector<T> to
this memory block? I would like to take advantage of the powerful vector<T>
member functions. Please note that I cannot copy the data into the vector
because the memory block is used/read by other objects.
 
Z

Zachary Turner

I have a pointer to a memory block. Is there a way I can map a vector<T> to
this memory block? I would like to take advantage of the powerful vector<T>
member functions. Please note that I cannot copy the data into the vector
because the memory block is used/read by other objects.

Why not -make- the memory block a vector instead? Then instead of
other objects reading the memory block, they read the vector. The C++
standard guarantees that data stored in a vector will be in contiguous
memory, so you can simply say &v[0] if you want to get a pointer to
the first byte of the block.

Alternatively, it might help to know which member functions of vector
you are interested in. The STL provides plenty of powerful methods
you can use on plain vanilla arrays, so maybe you don't really need a
vector at all.
 
B

barcaroller

Why not -make- the memory block a vector instead? Then instead of
other objects reading the memory block, they read the vector. The C++
standard guarantees that data stored in a vector will be in contiguous
memory, so you can simply say &v[0] if you want to get a pointer to
the first byte of the block.

Alternatively, it might help to know which member functions of vector
you are interested in. The STL provides plenty of powerful methods
you can use on plain vanilla arrays, so maybe you don't really need a
vector at all.

Unfortunately, the memory block is not allocated by me; all I have is a
pointer to it. It just occurred to me that even if I were able to map a
vector to a memory block, I would not be able to use any member function
that could potentially re-size the vector (since the memory block was
created using malloc and is not owned by me). The member functions I was
interested in were insert(), assign(), and erase().

What powerful plain-vanilla-array STL methods were you referring to?
 
I

Ian Collins

barcaroller said:
Why not -make- the memory block a vector instead? Then instead of
other objects reading the memory block, they read the vector. The C++
standard guarantees that data stored in a vector will be in contiguous
memory, so you can simply say &v[0] if you want to get a pointer to
the first byte of the block.

Alternatively, it might help to know which member functions of vector
you are interested in. The STL provides plenty of powerful methods
you can use on plain vanilla arrays, so maybe you don't really need a
vector at all.

Unfortunately, the memory block is not allocated by me; all I have is a
pointer to it. It just occurred to me that even if I were able to map a
vector to a memory block, I would not be able to use any member function
that could potentially re-size the vector (since the memory block was
created using malloc and is not owned by me). The member functions I was
interested in were insert(), assign(), and erase().
With the caveats you mention, you could provide an allocator as the
second template parameter to std::vector to map the block.
What powerful plain-vanilla-array STL methods were you referring to?
The standard algorithms.
 
Z

Zachary Turner

What powerful plain-vanilla-array STL methods were you referring to?

Algorithms in STL only care about iterators, the type of collection
doesn't generally matter. A pointer is actually a valid iterator, as
such all generic algorithms can operate on normal arrays. Copy, sort,
search, etc can all be performed on plain arrays. Example:

int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int x2[] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
std::copy(x, x+9, x2);

Inserting and deleting items are obviously container specific, however
so in that case you do need the member functions. A custom allocator
could almost have helped you deal with the malloc problem, but vector
being a stack based object will delete your memory block when going
out of scope, which obviously will be problematic.

It sounds like you may be out of luck. The only other possibility
would be that as soon as you receive a pointer to the buffer, copy it
into a vector, tell whoever owns it to go ahead and delete it, then
use the vector for everything. Of course, this may or may not work
depending on your situation and the design of the library that
allocates the buffer. But if you want to use a vector, the vector
must be allowed to own the memory for the items, there is no way
around that.
 
J

John Harrison

barcaroller said:
I have a pointer to a memory block. Is there a way I can map a vector<T> to
this memory block? I would like to take advantage of the powerful vector<T>
member functions. Please note that I cannot copy the data into the vector
because the memory block is used/read by other objects.

Write a custom allocator, that 'allocates' the pointer you need.

john
 
Z

Zachary Turner

Write a custom allocator, that 'allocates' the pointer you need.

john

If the allocator actually does something in its deallocate function,
his program will segfault at the end of scope of the vector since it
will delete memory owned by someone else. If the allocator does not
do something in its free function, it will introduce a memory leak
when vector reallocates memory after calling insert(), because it will
think that it freed the old memory and then try to allocate new memory.
 
J

John Harrison

Zachary said:
If the allocator actually does something in its deallocate function,
his program will segfault at the end of scope of the vector since it
will delete memory owned by someone else. If the allocator does not
do something in its free function, it will introduce a memory leak
when vector reallocates memory after calling insert(), because it will
think that it freed the old memory and then try to allocate new memory.

Apologies for any mistakes in the following, I don't have a copy of
Josuttis handy, but what I was thinking of was

template <class T>
struct FixedAllocator
{
T* allocate(size_t n) { return ptr; }
void deallocate(T* ptr, size_t n) {}
};

ptr could be global or it could be passed to the constructor. Apart from
ptr not pointing at enough memory, and not being able to copy a vector
with this allocator (I'm guessing the OP could live with this) I don't
see a problem.

john
 
K

Kai-Uwe Bux

John said:
Apologies for any mistakes in the following, I don't have a copy of
Josuttis handy, but what I was thinking of was

template <class T>
struct FixedAllocator
{
T* allocate(size_t n) { return ptr; }
void deallocate(T* ptr, size_t n) {}
};

ptr could be global or it could be passed to the constructor. Apart from
ptr not pointing at enough memory, and not being able to copy a vector
with this allocator (I'm guessing the OP could live with this) I don't
see a problem.

Uhm, I take it, you left out the other (required) members of the allocator
for the sake of brevity. A more complete version could look like this:

#include <cstddef>
#include <memory>

template < typename T >
struct fixed_allocator : public std::allocator<T> {
public:

typedef typename std::allocator<T>::pointer pointer;

fixed_allocator ( pointer ptr )
: std::allocator<T>()
, the_ptr ( ptr )
{}

template < typename U >
fixed_allocator ( fixed_allocator<U> const & other )
: std::allocator<T> ( other )
, the_ptr ( other.the_ptr )
{}

pointer allocate ( std::size_t ) {
return ( the_ptr );
}

void deallocate ( pointer, std::size_t ) {}

template < typename U >
struct rebind {
typedef fixed_allocator<U> other;
};

private:

pointer the_ptr;

}; // fixed_allocator


#include <vector>
#include <cassert>

typedef std::vector< char, fixed_allocator<char> > fixed_char_vector;

int main ( void ) {
char* cp = new char [1000];
fixed_allocator<char> ca ( cp );
fixed_char_vector v ( ca );
for ( unsigned int i = 0; i < 200; ++i ) {
v.push_back( char(i) );
}
assert( &v[0] == cp );
}


BTW: I am not sure whether the standard allows one to deduce that the assert
will not fail. However, an implementation would have to do something funny
to make it fail.


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,292
Messages
2,571,494
Members
48,180
Latest member
DelmarCarv

Latest Threads

Top