Instantiating class with custom allocator in shared memory
I'm pulling my hair due to the following problem: I am following the example given in boost.interprocess documentation to instantiate a fixed-size ring buffer buffer class that I wrote in shared memory. The skeleton constructor for my class is:
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
}
}
My first question: Does this sort of allocation guarantee that the buffer nodes are allocated in contiguous memory locations, i.e. when I try to access the n'th node from address m_start_ptr + n*sizeof(BufferNode)
in my Read()
method would it work? If not, what's a better way to keep the nodes, creating a linked list?
My test harness is the following:
// 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);
}
This gives me all kinds of compilation errors related to templates for the last statement. What am I doing wrong? Is segment.construct<M开发者_开发技巧yBuf>("MyBuffer")(100, alloc_inst)
the right way to provide the two template parameters?
My first question: Does this sort of allocation guarantee that the buffer nodes are allocated in contiguous memory locations, i.e. when I try to access the n'th node from address m_start_ptr + n*sizeof(BufferNode) in my Read() method would it work?
No. The reason being that you have the first node only. All BufferNode
objects that you create are not being saved (say, in a linked-list fashion) and contribute to memory leaks. Further, this style of allocation does not gurantee contiguous memory locations. Random access (as you state later in your question) will most likely fail. To get contiguous memory, you need to create an array (perhaps dynamic) of BufferNode
objects.
This gives me all kinds of compilation errors related to templates for the last statement. What am I doing wrong?
Difficult to say without knowing about the actual errors. Further, do you understand your code (and how Boost::Interprocess
fits in or how the allocator works)?
Note that the example you cite creates a vector
which is guaranteed to have contiguous memory for its contained objects. The only difference here is that the objects are created on a shared memory segment rather than the free store which is what typically happens when you don't specify an allocator as the second parameter and the default one is used.
精彩评论