boost - unordered_map with string in managed_shared_memory fails -
this code:
int main (int argc, char *argv[]) { typedef int keytype; typedef string mappedtype; typedef std::pair<keytype, mappedtype> valuetype; typedef boost::interprocess::allocator<valuetype, boost::interprocess::managed_shared_memory::segment_manager> shmalloc; typedef boost::unordered_map<keytype, mappedtype, boost::hash<keytype>, std::equal_to<keytype>, shmalloc> shmhashmap; boost::interprocess::managed_shared_memory segment(boost::interprocess::open_or_create, "containersharedmemory", 65536); if(argc == 2 && string(argv[1]) == "clear") { boost::interprocess::shared_memory_object::remove("containersharedmemory"); return 0; } shmhashmap *hash_map = segment.find_or_construct<shmhashmap>(boost::interprocess::unique_instance)(segment.get_segment_manager()); if(hash_map == null) { cout << "find_or_construct error" << endl; return 0; } for(int = 0; < 5; ++i) { shmhashmap::iterator iter = hash_map->find(i); if (iter == hash_map->end()) { hash_map->insert(valuetype(i, "test")); } } cout << "all..." << endl; for(shmhashmap::iterator iter = hash_map->begin(); iter != hash_map->end(); ++iter) { cout << iter->first << "|" << iter->second << endl; } cout << "end..." << endl; return 0; }
everything ok when mappedtype
int, segment fault whit code this:
rerun program access hash map in shared memory coredump
----------------------------edit again----------------------------------
the problem string solved sehe, thank , if design template class want hide detail, how do? if there perfect way
template<typename mappedtype> struct complexmappedtype { complexmappedtype(): t_access(0), t_expire(0) {} complexmappedtype(const mappedtype& v, uint32_t a, uint32_t e): value(v), t_access(a), t_expire(e) {} mappedtype value; uint32_t t_access; uint32_t t_expire; }; template <typename keytype, typename mappedtype> class mmshashmap { private: typedef complexmappedtype<mappedtype> datatype; typedef std::pair<keytype, datatype> valuetype; typedef boost::interprocess::allocator<valuetype, boost::interprocess::managed_shared_memory::segment_manager> shmalloc; typedef boost::unordered_map<keytype, datatype, boost::hash<keytype>, std::equal_to<keytype>, shmalloc> shmhashmap; public: mmshashmap(const std::string& name, size_t size, float e_thr, float e_scale); ~mmshashmap() {delete pmemorysegment;} size_t getmemsize() { return pmemorysegment->get_size(); } size_t getmemfreesize() { return pmemorysegment->get_free_memory(); } bool get(const keytype& key, mappedtype& value, uint32_t& expire); bool set(const keytype& key, const mappedtype& value, uint32_t expire); bool del(const keytype& key); private: void docapacityelimination(); std::string _name; boost::interprocess::managed_shared_memory* pmemorysegment; boost::shared_mutex mutex, mutex_eliminate; float feliminatethreshold, feliminatescale; };
of course. std::string
allocates heap.
the heap in process address space, other process reading same shared memory going wrong raw pointer there , invoke ub.
you need use shared-memory allocator strings too.
live on coliru (using mapped file coliru)
with shared memory:
#include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/allocators/allocator.hpp> #include <boost/container/scoped_allocator.hpp> #include <boost/container/string.hpp> #include <boost/unordered_map.hpp> #include <iostream> namespace bip = boost::interprocess; int main (int argc, char *argv[]) { typedef int keytype; typedef boost::container::basic_string<char, std::char_traits<char>, bip::allocator<char, bip::managed_shared_memory::segment_manager> > mappedtype; typedef std::pair<keytype, mappedtype> valuetype; typedef boost::interprocess::allocator<valuetype, boost::interprocess::managed_shared_memory::segment_manager> shmalloc; typedef boost::unordered_map<keytype, mappedtype, boost::hash<keytype>, std::equal_to<keytype>, boost::container::scoped_allocator_adaptor<shmalloc> > shmhashmap; boost::interprocess::managed_shared_memory segment(boost::interprocess::open_or_create, "containersharedmemory", 65536); if(argc == 2 && std::string(argv[1]) == "clear") { boost::interprocess::shared_memory_object::remove("containersharedmemory"); return 0; } shmhashmap *hash_map = segment.find_or_construct<shmhashmap>(boost::interprocess::unique_instance)(segment.get_segment_manager()); if(hash_map == null) { std::cout << "find_or_construct error" << std::endl; return 0; } for(int = 0; < 5; ++i) { shmhashmap::iterator iter = hash_map->find(i); if (iter == hash_map->end()) { hash_map->insert(valuetype(i, mappedtype { "hello", segment.get_segment_manager() })); } } std::cout << "all..." << std::endl; for(shmhashmap::iterator iter = hash_map->begin(); iter != hash_map->end(); ++iter) { std::cout << iter->first << "|" << iter->second << std::endl; } std::cout << "end..." << std::endl; }
prints
all... 4|hello 3|hello 2|hello 1|hello 0|hello end...
Comments
Post a Comment