3

I am attempting to store a vector of arbitrary elements in a memory mapped file (for now I'm trying to succeed with a vector of ints but it should work with vector of arbitrary objects). I have found plenty of documentation on doing so with shared memory, but not with memory mapped files proper. Since I have successfully made and used R-trees in memory mapped file (like in that example), I tried to replicate the process with vectors, but I guess I am missing some crucial element because it doesn't work. Here is my code:

namespace bi = boost::interprocess;
typedef bi::allocator<std::vector<int>, bi::managed_mapped_file::segment_manager> allocator_vec;
std::string vecFile = "/path/to/my/file/vector.dat";
bi::managed_mapped_file file_vec(bi::open_or_create,vecFile.c_str(), 1000);
allocator_vec alloc_vec(file_vec.get_segment_manager());
std::vector<int> * vecptr = file_vec.find_or_construct<std::vector<int> >("myvector")(alloc_vec);

Probably my last line is wrong, because "alloc_vec" is passed as an argument to the vector constructor, which doesn't expect it (I get among others the error /usr/include/c++/4.8/bits/stl_vector.h:248:7: note: candidate expects 0 arguments, 1 provided). However, I don't know then how to pass the allocator to find_or_construc(), which I assume is crucial for the vector to be properly created in the memory mapped file. Removing (alloc_vec) at the end of the last line leads to another error that I have more trouble to solve :

error: cannot convert ‘boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>::construct_proxy<std::vector<int> >::type {aka boost::interprocess::ipcdetail::named_proxy<boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>, std::vector<int>, false>}’ to ‘std::vector<int>*’ in initialization
std::vector<int> * vecptr = file_vec.find_or_construct<std::vector<int> >("myvector");

Any help will be greatly appreciated.`

jerorx
  • 568
  • 6
  • 19
  • 1
    There are always overloads taking the allocator, it's just that the allocator doesn't match the default `Allocator` template argument type (`std::allocator`) (see http://en.cppreference.com/w/cpp/container/vector) – sehe Apr 13 '15 at 10:18
  • Why are you trying this? Why (what for) do you want a vector (a "high-level container") in a memory mapped file (a low level thing).Please edit your question to improve it. – Basile Starynkevitch Apr 13 '15 at 10:23

1 Answers1

3

Like the samples show, tell the vector class about your custom allocator, so instead of

typedef std::vector<int>  MyVec;
MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(alloc_vec);

Use

typedef bi::allocator<int, bi::managed_mapped_file::segment_manager> int_alloc;
typedef std::vector<int, int_alloc>  MyVec;

int_alloc alloc(file_vec.get_segment_manager());
MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(alloc);

Note that

  • vector uses an allocator for the element types (not for the vector; segment_manager allocates that)
  • since the constructor for allocator<> is implicit, you can also just pass the segment_manager:

Live On Coliru

#include <boost/interprocess/managed_mapped_file.hpp>

namespace bi = boost::interprocess;

int main() {
    std::string vecFile = "vector.dat";
    bi::managed_mapped_file file_vec(bi::open_or_create,vecFile.c_str(), 1000);

    typedef bi::allocator<int, bi::managed_mapped_file::segment_manager> int_alloc;
    typedef std::vector<int, int_alloc>  MyVec;

    MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(file_vec.get_segment_manager());

    vecptr->push_back(rand());
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Your code crashes on MSVC14 in debug mode: https://stackoverflow.com/q/51334785/2741329. Do you have any idea of how to solve the issue? – gmas80 Jul 14 '18 at 14:20
  • Try to remove the mm file and let it be recreated. Also try to change to boost::container::vector Finally see this issue: https://github.com/boostorg/interprocess/issues/58 – Ray Hulha Oct 29 '19 at 11:54