在内存映射文件中存储向量

3

我试图将一个任意元素的向量存储在内存映射文件中(目前我正在尝试使用int向量,但应该也适用于任意对象向量)。我找到了很多关于使用共享内存进行操作的文档,但没有关于使用内存映射文件的正确方式。由于我已经成功地在内存映射文件中创建和使用过R树(就像那个例子所示),因此我尝试使用向量复制这个过程,但我想我缺少了一些重要的元素,因为它无法工作。这是我的代码:

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);

可能是因为"alloc_vec"被作为参数传递给向量构造函数,而向量构造函数并不需要它,所以我的最后一行可能是错误的。(我得到了其他错误提示,例如/usr/include/c++/4.8/bits/stl_vector.h:248:7: note: candidate expects 0 arguments, 1 provided)。然而,我不知道如何将分配器传递给find_or_construc(),我认为这对于在内存映射文件中正确创建向量至关重要。删除最后一行末尾的(alloc_vec)会导致另一个错误,我更难解决:
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");

任何帮助都将不胜感激。

1
总是有超载函数需要使用分配器,只是这个分配器不匹配默认的 Allocator 模板参数类型 (std::allocator<T>)(参见 http://en.cppreference.com/w/cpp/container/vector)。 - sehe
你为什么要尝试这个?你想在一个内存映射文件(一种低级别的东西)中使用向量(一种“高级容器”)是为了什么?请编辑你的问题以改进它。 - Basile Starynkevitch
1个回答

3

如示例所示,告诉向量类您的自定义分配器,因此不再使用默认分配器来分配内存:

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

使用

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);

请注意:
  • vector 使用一个元素类型的分配器(而不是 vector;segment_manager 分配那个)
  • 由于 allocator<> 的构造函数是隐式的,因此您也可以直接传递 segment_manager

在 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());
}

你的代码在MSVC14调试模式下崩溃:https://stackoverflow.com/q/51334785/2741329。你有什么解决办法吗? - gmas80
尝试删除mm文件并让它重新创建。同时尝试更改为boost :: container :: vector。最后查看此问题:https://github.com/boostorg/interprocess/issues/58 - Ray Hulha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接