Shared memory Vectors in boost with

2019-02-11 07:04发布

问题:

I have the following code. Trying to have a shared memory vector with structure having string and arrays. But when i compile the code I am getting error:

 usr/local/include/boost/container/vector.hpp:1819:4: error: no matching function for call to ‘InData::InData(InData* const&)’

Any suggestion how to fix this. I am new to Boost.

#include <iostream>
#include <string>
#include <cstdlib>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/vector.hpp>

using namespace boost::interprocess;

typedef boost::interprocess::basic_string<char> shared_string;

    struct InData
    {
        int X,Y,H,W;
        shared_string Label;
    };

    int main()
    {

        shared_memory_object::remove("MySharedMemory");
        managed_shared_memory managed_shm(create_only, "MySharedMemory", 10000);

        InData tData;// = managed_shm.construct<InData>("InDataStructure")();

        tData.Label = "Hello World";
        tData.H = 1;
        tData.W = 1;
        tData.Y = 1;
        tData.X = 1;

        typedef allocator<InData,managed_shared_memory::segment_manager> tStructData;
        typedef vector<InData,tStructData>  MyVector;

        //Initialize shared memory STL-compatible allocator
         tStructData alloc_inst (managed_shm.get_segment_manager());

         //Construct a vector named "MyVector" in shared memory with argument alloc_inst
          MyVector *myvector = managed_shm.construct<MyVector>("MyVector")(alloc_inst);

          //InData data;
          myvector->push_back(&tData);

        return 0;
    }

If just do myvector->push_back(tData)

/usr/local/include/boost/container/detail/advanced_insert_int.hpp:166:10: error: no match for ‘operator=’ (operand types are ‘InData’ and ‘const value_type {aka const InData}’)

回答1:

I've live-coded my review: recorded session

The fixed up code is below. Some of the notes (please watch the streaming session, though):

  1. you failed to give the "shared" string an allocator. That means it uses std::allocator and the allocations are done from the program heap. OOOPS. Your program will die, if you're lucky.

  2. once you give the shared_string the proper allocator, you'll find ripple effects. You need to pass in allocator instances at construction of shared_string because interprocess allocator instances are not default constructible.

    Rule Of Thumb: Stateful allocators are painful. If you avoid the pain, you're doing it wrong (and allocating from the wrong heap)

  3. naming is important:

    typedef allocator<InData, managed_shared_memory::segment_manager> tStructData;
    

    why name your allocator type tStructData? You might as well call it XXX. So, change it to

    typedef allocator<InData, managed_shared_memory::segment_manager> salloc;
    

    This took me while while I was trying to make sense of your code...

  4. Instead of explicitly creating alloc_inst, considering using the implicit conversion from segment_manager

  5. The line

    myvector->push_back(&tData);
    

    tries to push a pointer into a vector of class objects. That can never work, regardless of your allocator(s)

Live On Coliru

#include <iostream>
#include <string>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/vector.hpp>

using namespace boost::interprocess;

struct InData;
typedef allocator<InData, managed_shared_memory::segment_manager> salloc;

typedef boost::interprocess::basic_string<char, std::char_traits<char>, salloc::rebind<char>::other> shared_string;

struct InData {
    int X, Y, H, W;

    InData(salloc alloc) : Label(alloc) {}

    shared_string Label;
};

int main() {

    shared_memory_object::remove("MySharedMemory");
    managed_shared_memory managed_shm(create_only, "MySharedMemory", 10000);

    // Initialize shared memory STL-compatible allocator
    salloc alloc_inst(managed_shm.get_segment_manager());

    InData tData(alloc_inst); // = managed_shm.construct<InData>("InDataStructure")();

    tData.Label = "Hello World";
    tData.H = 1;
    tData.W = 1;
    tData.Y = 1;
    tData.X = 1;

    // Construct a vector named "MyVector" in shared memory with argument alloc_inst
    typedef vector<InData, salloc> MyVector;
    MyVector *myvector = managed_shm.construct<MyVector>("MyVector")(alloc_inst);

    // InData data;
    myvector->push_back(tData);
}