由于以下问题,我正在拉我的头发:我正在跟踪boost.interprocess文档中给出的the example来实例化我在共享内存中编写的固定大小的环缓冲区缓冲区类。我班级的骨架构造函数是:
template<typename ItemType, class Allocator >
SharedMemoryBuffer<ItemType, Allocator>::SharedMemoryBuffer( unsigned long capacity ){
m_capacity = capacity;
// Create the buffer nodes.
m_start_ptr = this->allocator->allocate(); // allocate first buffer node
BufferNode* ptr = m_start_ptr;
for( int i = 0 ; i < this->capacity()-1; i++ ) {
BufferNode* p = this->allocator->allocate(); // allocate a buffer node
}
}
我的第一个问题:这种分配是否保证缓冲节点分配在连续的内存位置,即当我尝试从m_start_ptr + n*sizeof(BufferNode)
方法中的地址Read()
访问第n个节点时会有用吗?如果没有,保留节点的更好方法是创建链表吗?
我的测试工具如下:
// Define an STL compatible allocator of ints that allocates from the managed_shared_memory.
// This allocator will allow placing containers in the segment
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
//Alias a vector that uses the previous STL-like allocator so that allocates
//its values from the segment
typedef SharedMemoryBuffer<int, ShmemAllocator> MyBuf;
int main(int argc, char *argv[])
{
shared_memory_object::remove("MySharedMemory");
//Create a new segment with given name and size
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
//Initialize shared memory STL-compatible allocator
const ShmemAllocator alloc_inst (segment.get_segment_manager());
//Construct a buffer named "MyBuffer" in shared memory with argument alloc_inst
MyBuf *pBuf = segment.construct<MyBuf>("MyBuffer")(100, alloc_inst);
}
这给了我与最后一个语句的模板相关的各种编译错误。我究竟做错了什么? segment.construct<MyBuf>("MyBuffer")(100, alloc_inst)
是提供两个模板参数的正确方法吗?
答案 0 :(得分:1)
我的第一个问题:这样吗? 分配保证缓冲区 节点是连续分配的 记忆位置,即当我尝试时 从地址访问第n个节点 m_start_ptr + n * sizeof(BufferNode)in 我的Read()方法会起作用吗?
没有。原因是您只有第一个节点。您创建的所有BufferNode
个对象都没有被保存(例如,以链表方式)并导致内存泄漏。此外,这种分配方式并不保证连续的内存位置。随机访问(正如您在问题中稍后陈述的内容)很可能会失败。要获得连续的内存,您需要创建一个BufferNode
个对象的数组(可能是动态的)。
这给了我与最后一个语句的模板相关的各种编译错误。我做错了什么?
在不知道实际错误的情况下很难说。此外,您是否了解您的代码(以及Boost::Interprocess
如何适应或分配器如何工作)?
请注意,您引用的示例会创建一个vector
,保证其包含的对象具有连续的内存。这里唯一的区别是对象是在共享内存段而不是免费存储上创建的,这是当你没有指定分配器作为第二个参数并且使用默认值时通常会发生的。