I’m trying to create a wrapper class to control a managed shared memory segment using Boost::Interprocess.  I’m having trouble reading data from the shared memory vector of strings…….

 

When the vector is instantiated in the managed shared segment I place in the first vector element a test string; “testing testing 1 2 3”.  Immediately after placing it there and in the scope of the same code block I can access the vector element and print out the string using std::cout.

 

However when I try to read the vector element using the read() function the test program crashes.  The problem is with the line:

 

std::string stdStr = sharedSegmentVector->at(index).c_str();

 

Question is how to fix this?  I’m confused because at instantiation time this same code will access the shared memory vector; later on in the read() function it will not.

 

I’ve as yet been unable to test the write() function; because I can’t yet read() the vector!

 

Any help to get this working is much appreciated,

 

With thanks,

 

Riskybiz

 

 

Class Definition:

 

#ifndef SHARED_MEMORY_WRAPPER_H//if not defined already

#define SHARED_MEMORY_WRAPPER_H//then define it

 

#include <boost/interprocess/managed_shared_memory.hpp>

#include <boost/interprocess/containers/vector.hpp>

#include <boost/interprocess/containers/string.hpp>

#include <boost/interprocess/allocators/allocator.hpp>

#include <boost/interprocess/sync/named_mutex.hpp>

 

#include <iostream>

#include <stdexcept>

 

 

using namespace boost::interprocess;

 

class SharedMemoryWrapper

{

public:

    SharedMemoryWrapper(const std::string &name, bool server) : m_name(name), m_server(server)

    {

if (server)

        {

            named_mutex::remove("named_mutex");

            shared_memory_object::remove(m_name.c_str());

        

//Create shared memory

managed_shared_memory m_segment(create_only, m_name.c_str(), 10000);        

            

//Create allocators

CharAllocator charallocator(m_segment.get_segment_manager());

StringAllocator stringallocator(m_segment.get_segment_manager());

 

//This string is in only in this process (the pointer pointing to the

//buffer that will hold the text is not in shared memory).

//But the buffer that will hold "this is my text" is allocated from

//shared memory

MyShmString mystring(charallocator);

mystring = "testing testing 1 2 3";

 

//This vector is fully constructed in shared memory. All pointers

//buffers are constructed in the same shared memory segment

//This vector can be safely accessed from other processes.

MyShmStringVector *sharedSegmentVector = m_segment.construct<MyShmStringVector>("sharedSegmentVector")(stringallocator);

  

sharedSegmentVector->push_back(mystring);

std::string outStr = sharedSegmentVector->at(0).c_str();

std::cout << "Shared Memory Vector Instantiated: Index 0 Data is: " << outStr << std::endl;

}

        else

        {

            //Open the shared segment

managed_shared_memory m_segment(open_only, name.c_str());

            //Find the vector using the c-string name and open it

MyShmStringVector *sharedSegmentVector = m_segment.find<MyShmStringVector>("sharedSegmentVector").first;

        }

       

m_mutex = new named_mutex(open_or_create, "named_mutex");

    }

 

    ~SharedMemoryWrapper()

    {

        if (m_server)

        {

            named_mutex::remove("named_mutex");

            //Destroy the vector from the managed_shared_memory

//m_segment->destroy_ptr(sharedSegmentVector);//This will free all strings that the vector contains

m_segment->destroy<MyShmStringVector>("sharedSegmentVector");//Destroy the vector

//Is it necessary to destroy the allocators here?

 

//Remove the managed_shared_memory; this may fail if the memory does not exist or is mapped or opened by another process

shared_memory_object::remove(m_name.c_str());

 

}

        delete m_mutex;

        delete m_segment;

}

 

    //Writer

void write(const std::string &in)

    {

    

try

{

CharAllocator charallocator(m_segment->get_segment_manager());

     scoped_lock<named_mutex> lock(*m_mutex);

MyShmString shmStr(in.c_str(), charallocator);

     sharedSegmentVector->push_back(shmStr);

}

catch(...)

{

std::cout << "Error in SharedMemoryWrapper::write(): unknown error" << std::endl;        

}

    }

   

//Reader

std::string read(int index)

{

try

{

scoped_lock<named_mutex> lock(*m_mutex);

std::cout << "Shared Memory Vector Entered Read(), Passed Index: " << index << std::endl;

std::string stdStr = sharedSegmentVector->at(index).c_str();

std::cout << "Shared Memory Vector Read At: Index" << index << "Data is: " << stdStr << std::endl;

return stdStr;

}

catch(std::range_error err)

{

std::cout << "Error in SharedMemoryWrapper::read(): range_error" << std::endl;

}

catch(...)

{                        

std::cout << "Error in SharedMemoryWrapper::read(): unknown error " << std::endl;        

}

return "ERROR IN SharedMemoryWrapper::read()";

}

 

 

private:

    //Typedefs

typedef boost::interprocess::allocator<char, managed_shared_memory::segment_manager> CharAllocator;

typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> MyShmString;

typedef boost::interprocess::allocator<MyShmString, managed_shared_memory::segment_manager> StringAllocator;

typedef boost::interprocess::vector<MyShmString, StringAllocator> MyShmStringVector;

 

bool m_server;

    std::string m_name;

 

managed_shared_memory *m_segment;

    MyShmStringVector *sharedSegmentVector;

named_mutex *m_mutex;

};//class

#endif//header guard

 

Test Programme:

 

#include "stdafx.h"

#include "SharedMemoryWrapper.h"

#include <iostream>

#include <string>

 

int main(int argc, char *argv[])

{

SharedMemoryWrapper *smw = new SharedMemoryWrapper("SharedMemory1", true);

 

std::string outStr  = smw->read(0);

 

std::cout << outStr << std::endl;

return 0;

}