When creating shared memory and memory mapped files to communicate two processes the memory segment can be mapped in a different address in each process:
#include<boost/interprocess/shared_memory_object.hpp> // ... using boost::interprocess; //Open a shared memory segment shared_memory_object shm_obj (open_only //open or create ,"shared_memory" //name ,read_only //read-only mode ); //Map the whole shared memory mapped_region region ( shm //Memory-mappable object , read_write //Access mode ); //This address can be different in each process void *addr = region.get_address(); This difficults the creation of complex objects in mapped regions: a C++ class instance placed in a mapped region might have a pointer pointing to another object also placed in the mapped region. Since the pointer stores an absolute address, that address is only valid for the process that placed the object there unless all processes map the mapped region in the same address.
To be able to simulate pointers in mapped regions, users must use offsets (distance between objets) instead of absolute
addresses. The offset between two objects in a mapped region is the same for
any process that maps the mapped region, even if that region is placed in different
base addreses. To facilitate the use of offsets, Boost.Interprocess
offers
struct structure { int integer1; //The compiler places this at offset 0 in the structure offset_ptr<int> ptr; //The compiler places this at offset 4 in the structure int integer2; //The compiler places this at offset 8 in the structure }; //... structure s; //Assign the address of "integer1" to "ptr". //"ptr" will store internally "-4": // (char*)&s.integer1 - (char*)&s.ptr; s.ptr = &s.integer1; //Assign the address of "integer2" to "ptr". //"ptr" will store internally "4": // (char*)&s.integer2 - (char*)&s.ptr; s.ptr = &s.integer2;
One of the big problems of
Some implementations choose the offset 0 (that is, an
In consequence,
using namespace boost::interprocess; offset_ptr<char> ptr; //Pointing to the next byte of it's own address //marks the smart pointer as null. ptr = (char*)&ptr + 1; //ptr is equal to null assert(!ptr); //This is the same as assigning the null value... ptr = 0; //ptr is also equal to null assert(!ptr); In practice, this limitation is not important, since a user almost never wants to point to this address.
|