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 namespace boost::interprocess; shared_memory_object shm_obj (open_only ,"shared_memory" ,read_only ); mapped_region region ( shm , read_write ); void *addr = region.get_address();
This makes the creation of complex objects in mapped regions difficult: 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 objects) 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 addresses. To facilitate the use of offsets, Boost.Interprocess offers offset_ptr
.
offset_ptr
wraps all the background operations needed to offer a pointer-like interface. The class interface is inspired in Boost Smart Pointers and this smart pointer stores the offset (distance in bytes) between the pointee's address and it's own this
pointer. Imagine a structure in a common 32 bit processor:
struct structure { int integer1; offset_ptr<int> ptr; int integer2; }; structure s; s.ptr = &s.integer1; s.ptr = &s.integer2;
One of the big problems of offset_ptr
is the representation of the null pointer. The null pointer can't be safely represented like an offset, since the absolute address 0 is always outside of the mapped region. Due to the fact that the segment can be mapped in a different base address in each process the distance between the address 0 and offset_ptr
is different for every process.
Some implementations choose the offset 0 (that is, an offset_ptr
pointing to itself) as the null pointer pointer representation but this is not valid for many use cases since many times structures like linked lists or nodes from STL containers point to themselves (the end node in an empty container, for example) and 0 offset value is needed. An alternative is to store, in addition to the offset, a boolean to indicate if the pointer is null. However, this increments the size of the pointer and hurts performance.
In consequence, offset_ptr
defines offset 1 as the null pointer, meaning that this class can't point to the byte after its own this pointer:
using namespace boost::interprocess; offset_ptr<char> ptr; ptr = (char*)&ptr + 1; assert(!ptr); ptr = 0; assert(!ptr);
In practice, this limitation is not important, since a user almost never wants to point to this address.
offset_ptr
offers all pointer-like operations and random_access_iterator typedefs, so it can be used in STL algorithms requiring random access iterators and detected via traits. For more information about the members and operations of the class, see offset_ptr reference
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4