Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would a pointer to object in boost shared memory become invalid when changing scope?

TL;DR : why would a pointer to an object in shared memory become invalid after a simple change of scope ? The pointer is not itself in the shared memory. Why would it be rendered useless ?


Let's say I have a simple custom data type for the sake of the example :

class CustomDataType
{
public:
  short val;
  CustomDataType(short val__) { val = val__; };
  virtual ~CustomDataType() {};
  short square() { return val*val; };
};

I have some function creating an instance of this object in a shared memory and returning a pointer to the object :

CustomDataType* someFunction()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{ open_or_create, "Boost", 1024 };
  CustomDataType *i = managed_shm.construct<CustomDataType>("CustomDataTypeObject")(7);
  std::cout << i->square() << std::endl;
  return i;
}

My main calls this function and then tries to access the pointer that is returned :

void main()
{
  CustomDataType* customData = someFunction();
  std::cout << customData->square() << std::endl; // <------- program crashes
}

The first call to the method 'square' through the pointer within the function works.

However, the second call to the method 'square' through the pointer in the main fails.

Why does the pointer not survive the change of scope ? I am in the same process, the object is still in memory.

Is the pointer rendered useless as soon as the managed_shared_memory gets out of scope, even though it does not change anything in the memory ?

Is there something I am missing to make the pointer survive the change of scope ?

I also tried replacing the standard pointer with an offset_ptr or passing the pointer by reference to the function instead of returning it. Nothing has modified the code's behaviour.

Minimal, Complete, and Verifiable example :

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream>

using namespace boost::interprocess;

class CustomDataType
{
public:
  short val;
  CustomDataType(short val__) { val = val__; };
  virtual ~CustomDataType() {};
  short square() { return val*val; };
};

CustomDataType* someFunction()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{ open_or_create, "Boost", 1024 };
  CustomDataType *i = managed_shm.construct<CustomDataType>("CustomDataTypeObject")(7);
  std::cout << i->square() << std::endl;
  return i;
}

void main()
{
  CustomDataType* customData = someFunction();
  std::cout << customData->square() << std::endl; // <------- program crashes
}
like image 879
Norgannon Avatar asked May 03 '26 14:05

Norgannon


2 Answers

The problem is that when the shared memory management object managed_shm goes out of scope, it is destroyed, and the shared memory is detached (so all pointers into it become invalid).

Normally, you use global variables for shared memeory management objects, so shared memory mappings remain valid until the program completes (unless explicitly destroyed).

like image 157
Chris Dodd Avatar answered May 05 '26 02:05

Chris Dodd


From the documentation:

When the managed_shared_memory object is destroyed, the shared memory object is automatically unmapped, and all the resources are freed.

This means that when managed_shm goes out of scope, the pointer i that you return becomes dangling.

like image 44
Justin Avatar answered May 05 '26 04:05

Justin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!