I am a little confused by the heap and by-value-vers-by-reference semantics associated with putting the std::string key and the large struct value in the container, for example boost::interprocess::map .
Here is my situation and some typedefs that I use:
typedef std::string AreaKeyType; typedef DATA_AREA_DESC AreaMappedType; // DATA_AREA_DESC is a big struct. typedef std::pair<const AreaKeyType, AreaMappedType> AreaValueType; typedef boost::interprocess::allocator<AreaValueType, boost::interprocess::managed_shared_memory::segment_manager> AreaShmemAllocator; typedef boost::interprocess::map<AreaKeyType, AreaMappedType, std::less<AreaKeyType>, AreaShmemAllocator> AreaMap;
This is how I insert an AreaValueType (which is a typedef for std :: pair):
AreaValueType A(areaKey, arearec); anAreaMap->insert(A);
I believe that the above code copies A, which is a std :: pair in my local (non-shared memory) stack, to the shared memory area. Can I get a handle to this shared memory area inside the boost :: interprocess :: card, or can you limit its selection and save it completely? (In other words, can I save something like a structure to the boost reprogramming card and then update one byte inside this record, or I just need to update the entire record, replacing all the bytes in the DATA_AREA_DESC structure, with a completely new byte.)
Some additional clarifications:
I have a plain old ANSI C DLL export api that internally uses C ++ and Boost :: interprocess :: map. The function is expected to create an element on the map and return a handle. How can I insert something into the boost :: interprocess :: map map and then return the handle to this object, other users other than C ++, it is preferable to discard on void* or unsigned long ? All I can do is extract material from shared memory by looking at the value of the std :: string key and write a new record to memory. I would like to save a reference to a shared memory object instead.
If I cannot do it directly, how would I do it indirectly? I suppose I could store std :: vector memory without memory and allocate std :: string non-shared memory by holding the areaKey value, which is std :: string, and then listing the void* element void* go back to std::string , and then use this to extract the record from the shared memory area. All this seems to be more work than should be strictly necessary for something so elementary. Maybe boost :: interprocess :: map is not suitable for my requirements?
What have i tried? This is what compiles, but I have no idea if I am doing this correctly. Somehow, I feel ugly at dereferencing the ::iterator returned from find , and then immediately taking its address like this:
void ** handle;
Update the above work. However, very reasonable advice in the answer below DOES NOT work. Using boost :: interprocess :: string results in a complete and complete crash and crashes at runtime. Using std :: string, which does not have the right to work, unless the Boost authors encoded in std :: string especially work, actually work fine.