在进程之间移动STL对象

时间:2012-02-11 20:34:38

标签: c++ stl

我知道这很奇怪,但我只是很开心。

我试图通过两台机器之间的套接字在两个进程之间传输std::map(在固定的内存区域中使用placement new进行实例化):MasterSlave。我正在使用的地图有typedef

   // A vector of Page objects
   typedef
      std::vector<Page*,
           PageTableAllocator<Page*> >
      PageVectorType;

   // A mapping of binary 'ip address' to a PageVector
   typedef
      std::map<uint32_t,
           PageVectorType*,
           std::less<uint32_t>,
           PageTableAllocator<std::pair<uint32_t, PageVectorType*> > >
      PageTableType;

PageTableAllocator<T>类负责将STL容器可能需要/需要的任何内存分配到内存中的固定位置。例如,所有Page个对象和STL内部结构都在这个固定的内存区域中实例化。这可确保std::map对象和分配器放置在固定的内存区域中。我已经使用GDB确保映射和分配器的行为正确(所有使用的内存都在固定区域,没有任何东西在应用程序的正常堆上)。

假设Master启动,初始化它的所有STL结构和特殊内存区域,会发生以下情况。 Slave启动,打印出页面表的版本,然后查找MasterSlave找到一个主页,删除其页面表版本,复制Master版本的页面表(以及特殊内存区域),成功将其打印出来页面表的Master版本。从我在GDB中所做的刺激开始,我可以执行许多只读操作。

尝试添加到新复制的PageTableType对象时,分配器的Slave方法中出现void construct (pointer p, const T& value)错误。传递给p的值指向已分配的内存区域(根据Master的{​​{1}}版本。)

我对C ++对象结构一无所知,但我猜测std::map的{​​{1}}版本的对象状态即使在我替换掉所有内存之后也必须闲着使用Slave及其分配器。 我的问题是,这是否是一个有效的问题。 C ++是否在对象实例化的内存区域之外维护某种对象状态?

地图中使用的所有对象都是非POD。分配器也是如此。

1 个答案:

答案 0 :(得分:3)

回答您的具体问题:

  

C ++是否在对象实例化的内存区域之外维护某种对象状态?

答案是。没有其他数据结构设置为“跟踪”对象或任何类型的对象。 C ++使用显式内存分配模型,因此如果您选择负责分配和释放,那么您就可以完全控制。

我怀疑你的代码在某处出现了问题,但是既然你认为代码是正确的,那么你就会发明一些其他原因导致你的代码失败,并遵循这条路径。我会退回去,仔细检查一下你的代码现在的工作方式,看看你是否可以确定问题。尽管STL类很复杂(尤其是std::map),但它们最终只是代码而且没有隐藏的魔法。