Following is a small reader writer program. The writer writes values to a map of maps, the write is successful.
There is another process called reader which reads the contents of the SHM, the reader has no problem in reading the key of the outer map, however if we try to access the contents of the inner map it crashes.
I have checked the container size and it prints 2 for case1 which is fine as the inner map contains 2 elements for the key "case1".
However, when I try to access to inner map the program crashes, is the way I am accessing the inner map not correct. Following are the code snippets that I am using.
ShmTypedefs.h
#ifndef __SHM_TYPE_DEFS__
#define __SHM_TYPE_DEFS__
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/map.hpp>
//the strings also need to be assigned from the shared memory
typedef boost::interprocess::allocator<void, boost::interprocess::managed_shared_memory::segment_manager> VoidAllocator;
typedef boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager> CharAllocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> SharedString;
//Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
//so the allocator must allocate that pair.
typedef SharedString KeyType;
typedef boost::interprocess::map<SharedString, int> MappedType;
typedef std::pair<const KeyType, MappedType> ValueType;
//allocator for the string
typedef boost::interprocess::allocator<SharedString, boost::interprocess::managed_shared_memory::segment_manager> StringAllocator;
//allocator of for the map.
typedef boost::interprocess::allocator<ValueType, boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
typedef boost::interprocess::allocator<ValueType, boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
//third parameter argument is the ordering function is used to compare the keys.
typedef boost::interprocess::map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MySHMMap;
#endif
writer.cxx
#include <boost/interprocess/containers/map.hpp>
#include <functional>
#include <utility>
#include <ShmTypedefs.h>
#include <iostream>
using namespace boost::interprocess;
int main ()
{
// remove earlier existing SHM
shared_memory_object::remove("SharedMemoryName");
// create new
managed_shared_memory segment(create_only,"SharedMemoryName",65536);
//Initialize the shared memory STL-compatible allocator
ShmemAllocator alloc_inst (segment.get_segment_manager());
//third parameter argument is the ordering function is used to compare the keys.
typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MySHMMap;
//offset ptr within SHM for map
//After construction m_pmap will contain the only object that has been consturcted in pmap[0]
//If we construct another object it will goto pmap[1]
offset_ptr<MySHMMap> m_pmap = segment.construct<MySHMMap>("MySHMMapName")(std::less<SharedString>(), alloc_inst);
//Insert data in the map
StringAllocator string_alloc_instance( segment.get_segment_manager() );
SharedString key("case1", string_alloc_instance );
SharedString inner_map_key("inner_case1", string_alloc_instance );
SharedString key1("case2", string_alloc_instance );
SharedString inner_map_key1("inner_case2", string_alloc_instance );
SharedString inner_map_key2("inner_case3", string_alloc_instance );
m_pmap[0][key][inner_map_key] = 2030;
m_pmap[0][key1][inner_map_key1] = 2031;
m_pmap[0][key][inner_map_key2] = 2034;
std::cout<<"
"<<m_pmap[0][key][inner_map_key]<< std::endl;
std::cout<<"
"<<m_pmap[0][key1][inner_map_key1]<< std::endl;
return 0;
}
reader.cxx
#include <boost/interprocess/containers/map.hpp>
#include <functional>
#include <utility>
#include <iostream>
#include <ShmTypedefs.h>
using namespace boost::interprocess;
int main ()
{
try
{
managed_shared_memory segment(open_or_create, "SharedMemoryName",65536);
int size= segment.find<MySHMMap>("MySHMMapName").second;
std::cout<< "size of map " << size << std::endl;
offset_ptr<MySHMMap> m_pmap = segment.find<MySHMMap>("MySHMMapName").first;
MySHMMap :: iterator iter = m_pmap[0].begin();
MySHMMap :: iterator iter_end = m_pmap[0].end();
for(; iter != iter_end; ++iter ) {
std::cout<<"
"<< iter->first<<std::endl;
if( iter->first == "case1" ) {
MappedType::iterator iti = (iter->second).begin();
MappedType::iterator iti_end = (iter->second).end();
for( ;iti != iti_end; ++iti ) {
std::cout << "symbol " << iti->first << " time " << iti->second << std::endl;
}
}
}
}
catch(std::exception &e) {
std::cout<<" error " << e.what() <<std::endl;
shared_memory_object::remove("SharedMemoryName");
}
return 0;
}
Stack Trace:
Output when I run the program =>
droy@apdeva01 shmmapofmap> ./bin/reader
size of map 1
case1
Matched case 1
Size of the inner container is 2 units
Segmentation fault (core dumped)
Core output:
(gdb) bt
#0 get_right () at /home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/intrusive/detail/rbtree_node.hpp:130
#1 next_node () at /home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/intrusive/detail/tree_algorithms.hpp:441
#2 next_node () at /home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/intrusive/rbtree_algorithms.hpp:353
#3 operator++ () at /home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/intrusive/detail/tree_node.hpp:119
#4 prot_incr ()
at /home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/interprocess/containers/container/detail/tree.hpp:326
#5 operator++ ()
at /home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/interprocess/containers/container/detail/tree.hpp:395
#6 __distance<boost::container::containers_detail::rbtree<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, std::pair<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > const, int>, boost::container::containers_detail::select1st<std::pair<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > const, int> >, std::less<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > >, std::allocator<std::pair<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > const, int> > >::iterator> ()
at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_iterator_base_funcs.h:79
#7 distance<boost::container::containers_detail::rbtree<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interproce---Type <return> to continue, or q <return> to quit---
ss::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, std::pair<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > const, int>, boost::container::containers_detail::select1st<std::pair<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > const, int> >, std::less<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > >, std::allocator<std::pair<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > const, int> > >::iterator> ()
at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_iterator_base_funcs.h:114
#8 main () at /home/user/droy/src/quotes/debshmutils/shmmapofmap/src/reader.cxx:33
See Question&Answers more detail:
os