2016-04-25 76 views
1

这是我的代码:unordered_map在managed_shared_memory字符串失败

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 i = 0; i < 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; 
} 

一切正常时MappedType是int,但是段故障丝毫这这样的代码: enter image description here

重新运行该程序访问在共享内存中哈希表将再次核心转储

----------------------------编辑--------- -------------------------

关于字符串的问题是通过sehe解决的,谢谢 ,如果我设计一个模板类想要隐藏那个细节,我该怎么办?如果有一些完美的方式

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; 
}; 
+0

如果你有一个新的问题,发布新问题。它可能是我链接的一个重复[下面](http://stackoverflow.com/questions/28608185/boostinterprocess-scoped-allocator-and-containers-of-containers-not-in-shared/28664248#28664248 ) – sehe

+0

好吧,我会看到你在该链接首先回答...谢谢〜 –

回答

2

当然。 std::string从堆分配。

堆在你的进程地址空间,所以任何其他进程读取相同的共享内存是会得到一个错误的原始指针有和调用UB。

您需要使用共享内存分配器与琴弦太。

Live On Coliru(使用Coliru映射文件)

共享内存:

#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 i = 0; i < 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; 
} 

打印

all... 
4|hello 
3|hello 
2|hello 
1|hello 
0|hello 
end... 
+0

我怎么能一个分配器分配到字符串,告诉我一些细节,谢谢 –

+0

汪汪汪。有些人有工作要做。对不起,延迟(PS。我有很多很多的答案,正是这些东西已经在网站上晃来晃去,你可以通过搜索帮助自己) – sehe

+0

无法粘贴代码...如果我封装了一个模板类,如下所示:template class MMSHashMap ....我怎么设计它来隐藏分配器的细节 –