2016-04-25 73 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 ....我怎麼設計它來隱藏分配器的細節 –