Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use boost::optional in interprocess memory?

Please consider following struct:

struct ThingThatWillGoInSharedMemory {
    boost::optional<int> opt_value;
};

I'm using boost::interprocess to create the shared memory area. My understanding of boost::optional was that it was a discriminated union rather than a nullable pointer. As a counter-example things like std::map and std::vector which use the heap need an explicit allocator to use them in interprocess memory, but boost::optional, I was fairly sure does not use the heap and is equivalent to writing:

struct ThingThatWillGoInSharedMemory {
    bool value_initialised;
    int value;
}

So it can be used out of the box. I'd be delighted if someone confirms this - I didn't see that the interprocess case was explicitly mentioned in the boost::optional docs, only implied.

like image 388
Benedict Avatar asked Nov 28 '13 16:11

Benedict


1 Answers

You're correct. boost::optional wraps values, rather than using pointer indirection. This means that plain old data objects such as ints can live in shared memory areas. In general objects utilizing the heap cannot be used in this way.

From the boost::optional documentation:

The difference between an optional and a pointer must be kept in mind, particularly because the semantics of relational operators are different: since optional is a value-wrapper...

boost::optional wraps values, instead of using pointers and indirection. Your basic model of boost::optional's memory layout is more or less correct. The actual implementation uses a union wrapping a generic aligned byte-buffer to avoid having to initialize the T object. The library uses the & (address-of) operator to get the locally mapped address of the byte-buffer in the process address space. This local memory address is then cast to a pointer or reference of type T.

Source code can be found at <boost/optional/optional.hpp>

like image 121
fredbaba Avatar answered Oct 04 '22 20:10

fredbaba