I'm using boost-1.68 and gcc-7.3.0 with -std=c++11. The following code as written throws a SIGSEGV for me.
The problem is caused by the combination of using std::unordered_map along with the boost interprocess shrink_to_fit() method. Changing the shared::unordered_map type from std::unordered_map to boost::unordered_map and/or commenting out the call to shrink_to_fit() will fix the code.
I ultimately don't intend to use std::unordered_map, but the fact that this minimal example is failing makes me concerned that I'm not properly setting up and/or not properly using the allocators.
Any insight would be appreciated.
#include <iostream>
#include <unordered_map>
#include <scoped_allocator>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/unordered_map.hpp>
#include <boost/lexical_cast.hpp>
using std::cout;
using std::endl;
namespace shared {
using segment_type = boost::interprocess::managed_mapped_file;
using segment_manager = segment_type::segment_manager;
template <typename T>
using Alloc = boost::interprocess::allocator<T, segment_manager>;
template <typename T>
using ScopedAlloc = std::scoped_allocator_adaptor<Alloc<T>>;
using string = boost::interprocess::basic_string<char, std::char_traits<char>, Alloc<char>>;
template <typename Key, typename Val, typename KHash = boost::hash<Key>, typename KEqual = std::equal_to<Key>>
using unordered_map =
std::unordered_map<Key, Val, KHash, KEqual, ScopedAlloc<std::pair<const Key, Val>>>;
}
struct MyStruct {
shared::unordered_map<shared::string, int> some_map;
MyStruct (shared::segment_manager *smgr)
: some_map{smgr}
{ }
friend std::ostream& operator<< (std::ostream& os, const MyStruct& m) {
os << "{";
for (auto& e : m.some_map) {
os << "{\"" << e.first << "\"," << e.second << "}";
}
os << "}";
return os;
}
};
int main () {
const char *filename = "content.bin";
std::remove(filename);
{
shared::segment_type segment(boost::interprocess::create_only, filename, (1<<20));
MyStruct *o1 = segment.construct<MyStruct>("MyStruct01")(segment.get_segment_manager());
o1->some_map.emplace("entry_1", 1);
o1->some_map.emplace("entry_2", 2);
o1->some_map.emplace("entry_3", 3);
cout << "constructed MyStruct01: " << *o1 << endl;
}
shared::segment_type::shrink_to_fit(filename);
{
shared::segment_type segment(boost::interprocess::open_read_only, filename);
MyStruct *o1 = (segment.find<MyStruct>("MyStruct01")).first;
cout << " found MyStruct01: " << *o1 << endl;
}
cout << "completed" << endl;
return 0;
}
Aucun commentaire:
Enregistrer un commentaire