unordered_map со строкой в ​​manage_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 является целым, но ошибка сегмента с этим кодом выглядит следующим образом: введите здесь описание изображения

Повторно запустите эту программу, чтобы получить доступ к хеш-карте в общей памяти.

------------------------------------------------------- --------------

проблема со строкой решена 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;
};

person Dylan Wang    schedule 25.04.2016    source источник
comment
Если у вас есть новый вопрос, опубликуйте новый вопрос. Скорее всего, это будет дубликат того, на который я ссылался 28664248">ниже   -  person sehe    schedule 25.04.2016
comment
Хорошо, я сначала прочитаю ваш ответ по этой ссылке... спасибо~   -  person Dylan Wang    schedule 25.04.2016


Ответы (1)


Конечно. std::string выделяет из кучи.

Куча находится в адресном пространстве вашего процесса, поэтому любой другой процесс, читающий ту же общую память, получит там неправильный необработанный указатель и вызовет UB.

Вам также нужно использовать распределитель общей памяти со строками.

Live On 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...
person sehe    schedule 25.04.2016
comment
как я могу назначить распределитель для строки, покажите мне некоторые детали, спасибо - person Dylan Wang; 25.04.2016
comment
Гав гав. У некоторых людей есть работа. Извините за задержку (PS. У меня есть много ответов, показывающих именно эти вещи, уже на сайте, вы могли бы помочь себе поиском) - person sehe; 25.04.2016
comment
не могу вставить код... если я инкапсулирую класс шаблона следующим образом: шаблон ‹имя типа KeyType, имя типа MappedType› класс MMSHashMap.... как я могу спроектировать его, чтобы скрыть детали распределителя - person Dylan Wang; 25.04.2016
comment
Ах. Пожалуйста, посмотрите мои существующие ответы. Мы поищем его для вас позже, если вы не сможете его найти. - person sehe; 25.04.2016
comment
stackoverflow.com/questions/28608185/ - person sehe; 25.04.2016