我知道这很奇怪,但我只是很开心。
我试图通过两台机器之间的套接字在两个进程之间传输std::map
(在固定的内存区域中使用placement new进行实例化):Master
和Slave
。我正在使用的地图有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
启动,打印出页面表的版本,然后查找Master
。 Slave
找到一个主页,删除其页面表版本,复制Master
版本的页面表(以及特殊内存区域),成功将其打印出来页面表的Master
版本。从我在GDB中所做的刺激开始,我可以执行许多只读操作。
尝试添加到新复制的PageTableType
对象时,分配器的Slave
方法中出现void construct (pointer p, const T& value)
错误。传递给p
的值指向已分配的内存区域(根据Master
的{{1}}版本。)
我对C ++对象结构一无所知,但我猜测std::map
的{{1}}版本的对象状态即使在我替换掉所有内存之后也必须闲着使用Slave
及其分配器。 我的问题是,这是否是一个有效的问题。 C ++是否在对象实例化的内存区域之外维护某种对象状态?
地图中使用的所有对象都是非POD。分配器也是如此。
答案 0 :(得分:3)
回答您的具体问题:
C ++是否在对象实例化的内存区域之外维护某种对象状态?
答案是否。没有其他数据结构设置为“跟踪”对象或任何类型的对象。 C ++使用显式内存分配模型,因此如果您选择负责分配和释放,那么您就可以完全控制。
我怀疑你的代码在某处出现了问题,但是既然你认为代码是正确的,那么你就会发明一些其他原因导致你的代码失败,并遵循这条路径。我会退回去,仔细检查一下你的代码现在的工作方式,看看你是否可以确定问题。尽管STL类很复杂(尤其是std::map
),但它们最终只是代码而且没有隐藏的魔法。