更改范围时,为什么boost共享内存中的对象的指针变为无效?

时间:2018-06-29 20:36:41

标签: c++ pointers boost shared-memory

TL; DR:在简单更改范围之后,为什么共享内存中的对象的指针变为无效?指针本身不在共享内存中。为什么会使其变得无用?


假设出于示例的原因,我有一个简单的自定义数据类型:

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
}

通过函数中的指针对方法'square'的第一次调用有效。

但是,通过主对象中的指针第二次调用方格方法失败。

为什么指针不能在范围更改中幸免?我处于同一过程中,该对象仍在内存中。

managed_shared_memory超出范围后,即使指针没有更改内存中的任何内容,指针也变得无用吗?

我是否缺少使指针在范围变化中生存下来的东西?

我还尝试用offset_ptr替换标准指针,或者将指针通过引用传递给函数,而不是返回它。没有任何改变代码的行为。

最小,完整和可验证的示例:

#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
}

2 个答案:

答案 0 :(得分:2)

问题在于,当共享内存管理对象managed_shm超出范围时,它将被破坏,并且共享内存被分离(因此进入该对象的所有指针都将变为无效)。

通常,您将全局变量用于共享内存管理对象,因此,共享内存映射在程序完成之前将一直有效(除非显式销毁)。

答案 1 :(得分:1)

来自the documentation

  

managed_shared_memory对象被破坏时,共享内存对象将自动取消映射,并且所有资源都将释放。

这意味着当managed_shm超出范围时,您返回的指针i会悬空。