choosyg
choosyg

Reputation: 794

Boost interprocess shared memory delete object without destroy

i have a boost interprocess managed_shared_memory on windows and i have a boost interprocess vector stored in it. The vector is created or opened by

auto* vec = shm.find_or_construct< MyVector >( "Data" )( shmAllocator );

as stated in the boost interprocess examples. My point is that i now constructed or opened an Object vec referencing the object inside the shared memory. I checked that the d'tor of vec is only called when i use shm.destroy<MyVector>("Data") and if i call delete vec the application crashes.

Now how do i properly release the object "vec" without destoying the underlying data? The complete Scenario:

In Windows operating systems, current version supports an usually acceptable emulation of the UNIX unlink behaviour: the file is renamed with a random name and marked as to be deleted when the last open handle is closed

Upvotes: 2

Views: 2758

Answers (1)

sehe
sehe

Reputation: 392931

The vector is created or opened by

This is slightly mixing up concepts. It's looked up, and constructed if necessary. (open_or_create applies to actual shareable objects like memory maps or shared memory objects).

I checked that the d'tor of vec is only called when i use shm.destroy<MyVector>("Data") and if i call delete vec the application crashes.

That's both by design.

One user exits the software and if i do not call destroy i have a memory leak,

Not really. If you don't destroy the vector, it still exists in the managed segment. This means that you can reopen the shared memory segment and still find it there.

To remove the shared segment, use remove()

The docs say this related to this:

When the managed_mapped_file object is destroyed, the file is automatically unmapped, and all the resources are freed. To remove the file from the filesystem you could use standard C std::remove or Boost.Filesystem's remove() functions, but file removing might fail if any process still has the file mapped in memory or the file is open by any process.

To obtain a more portable behaviour, use file_mapping::remove(const char *) operation, which will remove the file even if it's being mapped. However, removal will fail in some OS systems if the file (eg. by C++ file streams) and no delete share permission was granted to the file. But in most common cases file_mapping::remove is portable enough.

And here:

  1. ~basic_managed_mapped_file();

Destroys *this and indicates that the calling process is finished using the resource. The destructor function will deallocate any system resources allocated by the system for use by this process for this resource. The resource can still be opened again calling the open constructor overload. To erase the resource from the system use remove()

Additional info

If you really just want the vector gone after the last user releases it, use the interprocess shared_pointer: http://www.boost.org/doc/libs/1_64_0/doc/html/interprocess/interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.shared_ptr

Upvotes: 3

Related Questions