开发者

Instantiating class with custom allocator in shared memory

开发者 https://www.devze.com 2022-12-22 23:47 出处:网络
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 memo

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消