I want to share vector of objects using boost interprocess. The objects are from the following structure:
struct Foo
{
int id;
float time;
bool isFoo;
float myArray[7];
std::vector<int> vectorData;
};
I am creating boost inter process allocator and inter process vector:
typedef allocator<Foo, managed_shared_memory::segment_manager> FooAllocator;
typedef std::vector<Foo, FooAllocator> FooVector;
In my main function i initialize the memory segment, the allocator and the vector, based on:
boost -> creating vectors in shared memory
so:
managed_shared_memory mem_segment(open_or_create, "MemShare", 65536);
const FooAllocator alloc_inst(mem_segment.get_segment_manager());
fooVector = mem_segment.find_or_construct<FooVector>("FooVector")(alloc_inst);
Now, this is working for every data type in the Foo structure except vector. So if i try to share this i get all the members from Foo, and for vector data i get "Undefined memory location" I know that std::vector can't be shared directly. So i created new Foo structure with boost::interprocess:vector
struct FooInter
{
int id;
float time;
bool isFoo;
float myArray[7];
MyVector* pointcloud;
};
Where MyVector is:
typedef allocator<int, managed_shared_memory::segment_manager> VectorAllocator;
typedef boost::interprocess::vector<int, VectorAllocator> MyVector;
I am allocating memory for MyVector,
const VectorAllocator vec_alloc_inst(mem_segment.get_segment_manager());
MyVector* tmpVec = mem_segment.construct<MyVector>("MyVector")(vec_alloc_inst);
then what i try to do now is map the Foo to FooInter. I am mapping the vector data in for loop:
for (int t = 0; t < foo.vectorData.size()-1; t++) {
tmpVec->push_back(foo.vectorData[t]);
}
And then copy the tmpVec into fooInter.vectorData:
memcpy(fooInter.pointcloud, tmpVec, sizeof(int) * tmpVec->size());
This works but not for the whole size of foo.vectorData. So it works for 100 items, but if i go with foo.vectorData.size() it returns bad memory alloc.
Can somebody help me with this. I need to know the proper way to share a structure of this type. I feel that what i am doing is entirely wrong. Maybe i need to serialize the vector into string or something similar.
Edit:
Based on the answer from sehe:
I have object msg from type:
struct Foo
{
int id;
float time;
bool isFoo;
float myArray[7];
std::vector<int> pointcloud;
};
i need to pass that object in inter_foos. So in the code from sehe:
int main() {
auto segment = Shared::open();
auto& inter_foos = *segment.find_or_construct<InterFoos>("InterFoos")(segment.get_segment_manager());
// you can directly append to the shared memory vector
int nextid = inter_foos.size();
//instead of this
inter_foos.push_back({++nextid, 0, true, {.1,.2,.3,.4,.5,.6,.7}, Ints ({10,20,30}, segment.get_segment_manager()) });
//i need this
inter_foos.push_back({msg.id, msg.time, true, msg.myArray, Ints (msg.pointcloud, segment.get_segment_manager()) });
//i can't pass msg.poincloud to this object!!!
// or copy from a non-shared vector:
std::vector<Foo> const local {
{++nextid, 0, true, {.1,.2,.3,.4,.5,.6,.7}, {10,20,30} },
{++nextid, 1, true, {.2,.3,.4,.5,.6,.7,.8}, {20,30,40} },
{++nextid, 2, true, {.3,.4,.5,.6,.7,.8,.9}, {30,40,50} },
};
for (auto& local_foo : local)
inter_foos.emplace_back(local_foo);
// print the current contents
for (auto& foo : inter_foos)
std::cout << foo << "\n";
}