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
}
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).
From the documentation:
When the
managed_shared_memoryobject 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With