Mutex synchronised wrapper class for boost::interprocess shared memory vector of strings
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")(stringallocato r); 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; }
El 21/06/2013 18:13, Riskybiz escribió:
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:
You are instantiated managed_shared_memory m_segment as local variable. When the function ends, this class is destroyed and the shared memory unmapped. So accesing this shared memory will provoke an access violation error. Put this variable as a member variable. Best, Ion
participants (2)
-
Ion Gaztañaga
-
Riskybiz