|
Boost : |
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2006-12-29 03:51:35
Mathias Gaunard wrote:
> The boost inteprocess documentation [1] says that all objects must be
> constructed-destroyed via allocator::construct and allocator::destroy
> functions when using the interprocess allocators.
>
> However, according to the draft of the next C++ Standard [2] 20.1.6/2,
> allocator::construct is strictly equivalent to placement new and
> allocator::destroy stricly equivalent to a call to the destructor, with
> the pointer type casted to void*.
>
> Therefore why is such a requirement necessary?
Basically because the pointer type of Interprocess allocators is not a
raw pointer, but a relative one (offset_ptr). This way containers using
allocator::pointer as their pointer type can be mapped by different
processes, in different base addresses. If you try to do this:
using boost::interprocess;
typedef allocator<MyClass, managed_shared_memory::segment_manager> MyAlloc;
managed_shared_memory mem();
MyAlloc alloc(mem.get_segment_manager());
MyClass *myclass = new(alloc.allocate(1)) MyClass;
you will get a compilation error, because "allocate" returns
allocator::pointer and that pointer is not MyClass * but
offset_ptr<MyClass>. You can get the raw pointer from offset_ptr<> using
offset_ptr<T>::get() method. That's why containers should use
allocator::construct() that is defined like:
void construct(const pointer &ptr, const Convertible &value)
{ new(detail::get_pointer(ptr)) value_type(value); }
It's conforming for a STL container to ignore allocator::pointer and
suppose it's a raw pointer, but this sadly can support shared memory or
any other smart pointer based allocators.
Regards,
Ion
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk