Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to place std::vector to shared memory?

Tags:

c++

stl

i would to create std::vector in shared memory using CreateFileMapping() windows API function. I know how to create shared memory and manage it, but how to place std::vector to fixed address in memory? I can't use boost or other libraries in my case, i am using CBuilder++ 2010. One variant i think is maybe use

std::vector<int> myVec; 
myVec *mv;
mv = shared_memory_addr ?

But how do i detect real size of vectors to resize memory?

like image 281
Sergey Avatar asked Mar 19 '11 17:03

Sergey


People also ask

Is std::vector contiguous in memory?

Yes, the elements of a std::vector are guaranteed to be contiguous.

How do I allocate memory with std::vector?

An std::vector manages its own memory. You can use the reserve() and resize() methods to have it allocate enough memory to fit a given amount of items: std::vector<int> vec1; vec1. reserve(30); // Allocate space for 30 items, but vec1 is still empty.

How do you assign a vector to a memory in C++?

Using std::vector::reserve whenever possible Vectors are assigned memory in blocks of contiguous locations. When the memory allocated for the vector falls short of storing new elements, a new memory block is allocated to vector and all elements are copied from the old location to the new location.

Is std::vector stored on the heap?

std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator).


2 Answers

I'd use Boost.Interprocess, which has an explanation of how to do just this: http://www.boost.org/doc/libs/1_38_0/doc/html/interprocess/quick_guide.html#interprocess.quick_guide.qg_interprocess_container

Note that this does not use std::vector<>, which is not suitable for shared-memory use, because it is typically implemented in terms of three pointers (begin, end, capacity, or some equivalents), and addresses will differ between processes. So Boost.Interprocess has its own vector class, which is purpose-built for what you are trying to do.

like image 133
John Zwinck Avatar answered Sep 30 '22 21:09

John Zwinck


Actually, you have to do both: use placement new to construct the std::vector instance in shared memory AND use a custom allocator to make the vector place its data within the shared memory as well.

Keep in mind that you need to synchronize any access to the vector (except if you need only read access) - std::vector is not generally thread-safe and doesn't declare any of its members volatile, which makes simultaneous access out of the compiler's scope - as it happens in a shared memory region - extremely dangerous.

... after all, I wouldn't do it. Shared memory is a very low-level, very tricky concept, it doesn't fit well with high-level data containers such as std::vector, in a language that (as of cpp03) doesn't provide good builtin solutions for concurrency problems and that is not aware that something like shared memory exists.

... it might even trigger undefined behaviour: while std::vector generally uses its allocator to fetch storage for its elements, it is (as far as I know) allowed to allocate further memory (i.e. for internal purposes, whatever that may be) using malloc or any other allocation strategy (I think Microsoft's std::vector implementation does that in debug builds) ... these pointers would only be valid for one side of the memory mapping.

To avoid the std::vector, I'd simply allocate sufficient memory in the mapped range upfront and use a simple counter to keep the number of valid elements. That should be safe.

like image 23
Alexander Gessler Avatar answered Sep 30 '22 21:09

Alexander Gessler