0

I'm a little confused about Boost::interprocess shared memory and deallocation.

When creating a new object on the stack in C++, you simply declare the type, the variable name, and the parameters to the constructor (unless you want a default constructor):

 AType AVariableName(param1,param2); 

If that same variable is to be allocated using Boost::interprocess I am doing something like this. I apologize for the dense series of typedefs but I can't think how to ask this question and be specific without giving real boost templated type expansions.

typedef int                   PointKeyType;
typedef DATAPOINT                 PointMappedType;
typedef std::pair<const int, PointMappedType> PointValueType;
typedef boost::interprocess::allocator<PointValueType, 
  boost::interprocess::managed_shared_memory::segment_manager> PointShmemAllocator;
typedef boost::interprocess::map<PointKeyType, 
  PointMappedType, std::less<PointKeyType>, PointShmemAllocator> PointMap;

So far above all I've done is define that I'm making an <integer,DATAPOINT> std::map-like entity in shared memory and I haven't said what DATAPOINT is, but it's a struct defined with some float, and integer values in it. In the application that owns and initial creates the shared memory map I initialize it like this, mostly borrowed code from a Boost demo:

   managed_shared_memory segment
      ( open_or_create  // or maybe it should be create_only?
       ,MEMORY_AREA_NAME // a string literal
       ,65536);          //segment size in bytes


   // STL compatible allocator
   PointShmemAllocator point_alloc_inst (segment.get_segment_manager());

Now I use the allocator like this, creating boost::interprocess::map<...> using the typedef PointMap:

 PointMap *aPointMap = 
       segment.construct<PointMap>("SOMEOBJECT_NAME_HERE")                                  (std::less<PointKeyType>() //first  ctor parameter
                                 ,point_alloc_inst);     

Now suppose I want to dispose of this boost::interprocess::map object I call a PointMap, and reuse its memory. How do I do that?

I tried something like this:

segment.destruct<PointMap>(aPointMap);

But the syntax is not exactly orthogonal here. Then I I thought, maybe it's some thing like the placement syntax of destructors, but I haven't been able to figure it out.

If it's all magic and it just works, and I am just supposed to just delete PointMap, and that's all there is to it, I'll feel a bit silly, but I want to make sure I'm not making a big mistake.

Secondly, I am assuming that the secondary processes that access this shared memory are simply handled the same way, but I would use the find<T> methods like this:

      std::pair<PointMap*, std::size_t> f = segment->find<PointMap>("SOMEOBJECT_NAME_HERE");
      aPointMap = f.first;

And then, when I'm done with it, delete aPointMap or just set aPointMap = NULL?

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • Apologies in advance, but while waiting for someone to post an answer you could step through the code that's executed when you 'delete PointMap' - if nothing else, you'll gain a bit of insight into how the library is implemented. Who knows - you might just answer your own question. – Bukes Mar 17 '13 at 20:32
  • I am going to try it but so far I haven't understood 99% of what I read inside the boost headers. :-( – Warren P Mar 17 '13 at 20:33
  • P - Yeah, BOOST sources can be terse. Once you stare at it for a while it'll clear up :-) – Bukes Mar 17 '13 at 20:35

1 Answers1

1

See the docs which give a complete example of what you want to do. The map example doesn't destroy the container, but the vectors one does.

PointMap *aPointMap =
       segment.construct<PointMap>("SOMEOBJECT_NAME_HERE")
                                 (std::less<PointKeyType>() //first  ctor parameter
                                 ,point_alloc_inst);

That creates an object named "SOMEOBJECT_NAME_HERE" so to destroy it you just destroy that named object:

segment.destroy<PointMap>("SOMEOBJECT_NAME_HERE");

This is arguably orthogonal: you create an object by name and pass arguments, then destroy it by name (but don't need arguments because destructors don't take arguments.)

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • Is this construct/destroy naming convention specific to boost or is it an STD-C++-LIB or STL convention? – Warren P Mar 18 '13 at 00:01
  • Using `construct` and `destroy` with a template argument list is specific to Boost.Interprocess, but standard C++ allocators have members called `construct` and `destroy`, and those names obviously come from constructors and destructors in the core language – Jonathan Wakely Mar 18 '13 at 01:36
  • Okay that makes sense. And if I only FOUND it with `find` I just forget the reference by nil-the-variable-out and don't dispose at all, right. – Warren P Mar 18 '13 at 12:54
  • One of your processes should be responsible for destroying the container, there should be exactly one `construct<>` and exactly one `destroy<>` for each shared container. Whether you obtain a reference to it by `find<>` or not is orthogonal, you destroy it by name anyway not by using the reference you get from `find<>` – Jonathan Wakely Mar 18 '13 at 17:27
  • Thanks very much. Incidentally I found you can get some nifty heap corruption by invoking "delete x" on pointers to objects that were supposed to be destroyed by `segment.destroy` :-) – Warren P Mar 23 '13 at 15:45