4

I'm using boost 1.53 and GCC 4.1.2. I've tried to use boost unordered_map in some tests (documentation says, that it should work with shared memory), but i'm unable to compile my code. With interprocess::map instead of unordered everything is ok.

Typedefs:

typedef boost::interprocess::allocator<char, SegmentManager> CharAllocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> ShmString;
typedef ShmString  HashKeyType;
//ComplexType is a wrapper for internal interprocess::map
typedef ComplexType  HashMappedType;
typedef std::pair<const ShmString, ComplexType> HashValueType;

typedef boost::interprocess::allocator<HashValueType,
  boost::interprocess::managed_shared_memory::segment_manager> HashMemAllocator;

typedef boost::unordered_map
  < HashKeyType           , HashMappedType
  , boost::hash<HashKeyType>  ,std::equal_to<HashKeyType>
  , HashMemAllocator>
TestHashMap;

Allocation:

boost::interprocess::managed_shared_memory segment( boost::interprocess::open_or_create, "MySharedMemory", 65536);
thm_ = segment.construct<TestHashMap>("TestHashMap")
      (3, boost::hash<ShmString>(), std::equal_to<ShmString>()
      , segment.get_allocator<HashValueType>());

Usage:

boost::interprocess::managed_shared_memory segment( boost::interprocess::open_only, "MySharedMemory");
ShmString str("123.345", segment.get_allocator<ShmString>());

ComplexType th("MySharedMemory");

HashValueType value(str, th);
thm_->insert(value);

And here is some error output:

../boost/include/boost/unordered/detail/allocate.hpp: In instantiation of 'boost::unordered::detail::allocator_traits<boost::interprocess::allocator<boost::unordered::detail::ptr_node<std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >::pointer_to_other<const boost::unordered::detail::ptr_node<std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> > >':
../boost/include/boost/unordered/detail/allocate.hpp:527:   instantiated from 'boost::unordered::detail::allocator_traits<boost::interprocess::allocator<boost::unordered::detail::ptr_node<std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >'
../boost/include/boost/unordered/detail/unique.hpp:114:   instantiated from 'boost::unordered::detail::pick_node<boost::interprocess::allocator<std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> >, std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> >'
../boost/include/boost/unordered/detail/unique.hpp:158:   instantiated from 'boost::unordered::detail::map<boost::interprocess::allocator<std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> >, 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared, boost::hash<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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > > >, std::equal_to<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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > > > >'
../boost/include/boost/unordered/unordered_map.hpp:59:   instantiated from 'boost::unordered::unordered_map<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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared, boost::hash<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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > > >, std::equal_to<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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > > >, boost::interprocess::allocator<std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >'
utest/THUnitTests.cc:96:   instantiated from here
../boost/include/boost/unordered/detail/allocate.hpp:523: error: ambiguous class template instantiation for 'struct boost::pointer_to_other<boost::interprocess::offset_ptr<boost::unordered::detail::ptr_node<std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> >, long int, long unsigned int, 0u>, const boost::unordered::detail::ptr_node<std::pair<const 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, long int, long unsigned int, 0u>, 0ul>, boost::interprocess::iset_index> > >, TINHolderShared> > >'
../boost/include/boost/interprocess/offset_ptr.hpp:721: error: candidates are: struct boost::pointer_to_other<boost::interprocess::offset_ptr<T1, P1, O1, A1>, U>
../boost/include/boost/pointer_to_other.hpp:29: error:                 struct boost::pointer_to_other<Sp<T>, U>
../boost/include/boost/pointer_to_other.hpp:36: error:                 struct boost::pointer_to_other<Sp<T, T2>, U>
../boost/include/boost/pointer_to_other.hpp:43: error:                 struct boost::pointer_to_other<Sp<T, T2, T3>, U>

I'm not sure if the problem is in my code, or because of old compiler version. If the problem is with compiler, then could it be fixed with newer version of boost? (i can't update my GCC). Or maybe there are some implementations of hash table, that are compatible with shared memory and with my compiler?

trvecvlt
  • 102
  • 1
  • 10
  • 3
    Not only is your compiler several years out of date, it [wasn't an official release](http://stackoverflow.com/questions/23816420/what-is-gcc-4-1-3). I'd seriously reconsider whether or not you can update it. – Mike Seymour Apr 10 '15 at 09:28
  • @MikeSeymour, just checked, my mistake, i have 4.1.2. If it were up to me, to choose GCC version, i'd update it immediately, but there is nothing i can do with it. – trvecvlt Apr 10 '15 at 09:41
  • `boost::interprocess::string` is **not** automatically shared (it doesn't use interprocess allocators unless you tell it to). Same for `bip::map` Post a SSCCE. Your sample is not selfcontained. – sehe Apr 10 '15 at 09:48
  • @sehe, i've added typedefs for my string. about map, I'm not sure if i should post `ComplexType` allocation here, because it's qiute huge and not really related to the problem (it's posted in another [question](http://stackoverflow.com/questions/29518728/boost-interprocess-flat-map-operator-compilation-errors) ). If i'll change `unordererd_map` to `bip::map`, this code will compile with current ComplexType, so i think problem is somewhere else. – trvecvlt Apr 10 '15 at 10:10
  • I [commented on the other question](http://stackoverflow.com/questions/29518728/boost-interprocess-flat-map-operator-compilation-errors#comment47267656_29518728). Have a look at my answer. I'll be happy to know what else needs clarification – sehe Apr 10 '15 at 10:15

1 Answers1

3

Here's a fixed up version.

I just tried to make it self contained according to the suggestive comments. And it works.

Hope it helps anyways:

Live On Coliru

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/unordered_map.hpp>

namespace bip = boost::interprocess;
// ShmString is boost::interprocess::basic_string
typedef bip::allocator<char, bip::managed_shared_memory::segment_manager> CharAllocator;
typedef bip::basic_string<char, std::char_traits<char>, CharAllocator> ShmString;
typedef ShmString HashKeyType;
// ComplexType is a wrapper for internal interprocess::map
struct ComplexType {
    typedef bip::allocator<std::pair<int const, int>, bip::managed_shared_memory::segment_manager> Alloc;
    typedef bip::map<int, int, std::less<int>, Alloc> Map;

    template <typename Alloc2>
    ComplexType(std::string, Alloc2 const& alloc = {}) : map(alloc) {}
    Map map;
};

typedef ComplexType HashMappedType;
typedef std::pair<const ShmString, ComplexType> HashValueType;
typedef bip::allocator<HashValueType, bip::managed_shared_memory::segment_manager> HashMemAllocator;
typedef boost::unordered_map<HashKeyType, HashMappedType, boost::hash<HashKeyType>, std::equal_to<HashKeyType>, HashMemAllocator>
    TestHashMap;

int main()
{
    // Allocation:
    {
        bip::managed_shared_memory segment(bip::open_or_create, "MySharedMemory", 65536);
        auto thm_ = segment.construct<TestHashMap>("TestHashMap")(3, boost::hash<ShmString>(), std::equal_to<ShmString>(),
                segment.get_allocator<HashValueType>());

    }
    // Usage:
    bip::managed_shared_memory segment(bip::open_only, "MySharedMemory");
    auto thm_ = segment.construct<TestHashMap>("TestHashMap")(3, boost::hash<ShmString>(), std::equal_to<ShmString>(), segment.get_allocator<HashValueType>());
    ShmString str("123.345", segment.get_allocator<ShmString>());

    ComplexType th("MySharedMemory", segment.get_segment_manager());

    HashValueType value(str, th);
    thm_->insert(value);
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Which version of GCC are you using? There is `auto`, so think it's quite modern =) The code looks correct, but on my GCC 4.1.2, i'm getting the same errors. Seems like the only option for me is to try newer boost or just use maps. – trvecvlt Apr 10 '15 at 10:44
  • 1
    I assume you replaced auto with the type name? Are you sure you don't have some "using namespace" thing wreaking havoc? (Even if embedded in some namespace in a header) fyi The allocators have converting constructors (implicit rebinds) and you can implicitly construct them from the `mmf.get_segment_manager()` too. Also, see the comment at your previous question. – sehe Apr 10 '15 at 11:30
  • Wait a second though. `auto` support was released in [GCC 4.4, since April 21, 2009](https://gcc.gnu.org/gcc-4.4/changes.html). I don't see how "6 years old" equates to "quite modern =)" – sehe Apr 10 '15 at 11:53
  • yes, i replaced it. I removed all includes except system and boost and commented all my code, so the only difference is type instead of auto and no default initializer here `Alloc2 const& alloc = {}`. And thanks for link under another question=) – trvecvlt Apr 10 '15 at 13:22