I am trying to create a POD struct type and keep a vector of that struct in boost interprocess shared memory. What I have been doing and it's been working:
template <typename T>
using Alloc = ipc::allocator<T, ipc::managed_shared_memory::segment_manager>;
using String = ipc::basic_string<char, std::char_traits<char>, Alloc<char>>;
struct SharedData
{
template <typename Alloc>
SharedData(size_t aSize, std::string_view aStr, Alloc alloc) : sz(aSize), data(aStr, alloc) {}
size_t sz;
String data;
};
I go ahead and create a vector of this struct which is cool and works, but I wanted to get cache locality when accessing i'th index of the vector. For that I wanted to get, data to be present in the same contiguous storage of the vector, so I changed the struct to:
struct SharedData
{
SharedData(size_t aSize) : sz(aSize) {}
size_t sz;
char data[MAX_DATA_SIZE];
};
But this does not get allocated in the vector, when I create it using:
auto shared_vec = segment_.construct<Vector<SharedData>>((const char *) shared_vec_name.c_str())(segment_.get_segment_manager());
for (int i = 0; i < vector_size; i++)
(*shared_vec).emplace_back(max_data_size);
It throws:
terminate called after throwing an instance of 'boost::interprocess::bad_alloc'
what(): boost::interprocess::bad_alloc
Any idea what am I doing wrong here? I want to allocate a vector of POD type with cache locality as well, since String will have further dynamic allocations which is not desirable for my use case.
char data[MAX_DATA_SIZE];makessizeof(SharedData)much larger. Depending on allocation pattterns the vector might reserve or reallocate running out of space in your segment.Note that many string implementations have SSO, which means you may already have cache locality.
If you're really striving for POD data and complete cache control, I'd suggest switching to something like
for some fixed capacity
N. In that case you wouldn't need a managed segment, so consider usingboost::interprocess::mappped_regiondirectly instead ofmanaged_shared_memory.Note that there are many ways in between as well. Thinking of
boost::static_vectororboost::small_vector. Also, consider that **simply doing a.reserve()up-front may solve your problems:Bad alloc is thrown
boost::interprocess::managed_mapped_file deque of strings runs out of space