【问题标题】:Why would a pointer to object in boost shared memory become invalid when changing scope?为什么更改范围时指向boost共享内存中对象的指针会变得无效?
【发布时间】:2018-12-09 01:58:10
【问题描述】:

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

我的 main 调用了这个函数,然后尝试访问返回的指针:

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

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

但是,通过 main 中的指针对方法“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
}

【问题讨论】:

  • [Off Topic] void main() 是错误的。它必须是int main(/* can be params here */)
  • 它确实使 Minimal [...] 示例略小。

标签: c++ pointers boost shared-memory


【解决方案1】:

问题是当共享内存管理对象managed_shm超出范围时,它被销毁,共享内存被分离(因此所有指向它的指针都变得无效)。

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

【讨论】:

  • 如果 managed_shared_memory 保留在全局变量中对于其他访问它的进程来说不是问题,我想这就是我要做的!谢谢 ! :)
【解决方案2】:

来自the documentation:

当managed_shared_memory对象被销毁时,共享内存对象自动解映射,所有资源被释放。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多