You could use shared memory, mapped at a fixed address, i.e., the address would be the same in each process allowing using raw pointers.
So if you do something like the following, you can have (multiple) regions of shared memory:
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
struct MySegment {
static const size_t alloc_size = 1048576;
static const void *getAddr() { return (void *)0x400000000LL; }
static const char *getSegmentName() { return "MySegment"; }
};
template <typename MemorySegment>
class SharedMemory {
public:
typedef boost::interprocess::fixed_managed_shared_memory shared_memory_t;
typedef shared_memory_t::segment_manager segment_manager_t;
static shared_memory_t *getSegment() {
if (!segment) {
assert(MemorySegment::getAddr() != 0 && "want a fixed address for all processes");
segment = new boost::interprocess::managed_shared_memory(
boost::interprocess::open_or_create,
MemorySegment::getSegmentName(),
MemorySegment::alloc_size,
MemorySegment::getAddr());
}
return segment;
}
static segment_manager_t *getSegmentManager() {
return getSegment()->get_segment_manager(); }
private:
static boost::interprocess::managed_shared_memory *segment;
};
template <typename MemorySegment>
typename SharedMemory<MemorySegment>::shared_memory_t *SharedMemory<MemorySegment>::segment = NULL;
template <class MemorySegment, class T>
class SharedMemoryAllocator {
public:
typedef boost::interprocess::allocator<T, typename SharedMemory<MemorySegment>::segment_manager_t> InterprocessAllocator;
// Delegate all calls to an instance of InterprocessAllocator,
pointer allocate(size_type n, const void *hint = 0) { return TempAllocator().allocate(n, hint); }
void deallocate(const pointer &p, size_type n) { return TempAllocator().deallocate(p, n); }
size_type max_size() const { return TempAllocator().max_size(); }
void construct(const pointer &ptr, const_reference v) { return TempAllocator().construct(ptr, v); }
void destroy(const pointer &ptr) { return TempAllocator().destroy(ptr); }
typedef typename InterprocessAllocator::value_type value_type;
typedef typename InterprocessAllocator::pointer pointer;
typedef typename InterprocessAllocator::reference reference;
typedef typename InterprocessAllocator::const_pointer const_pointer;
typedef typename InterprocessAllocator::const_reference const_reference;
typedef typename InterprocessAllocator::size_type size_type;
typedef typename InterprocessAllocator::difference_type difference_type;
SharedMemoryAllocator() {}
template <class U> SharedMemoryAllocator(const SharedMemoryAllocator<MemorySegment, U> &u) {}
template <typename OtherT> struct rebind { typedef SharedMemoryAllocator<MemorySegment, OtherT> other; };
private:
static InterprocessAllocator TempAllocator() {
return InterprocessAllocator(SharedMemory<MemorySegment>::getSegmentManager());
}
};
Then, you could use:
std::vector<int, SharedMemoryAllocator<MySegment, int> vec;
and the vector's elements would be put in shared memory (of course, vec
will also have to be allocated there).