当尝试使用boost::interprocess
在存储器映射文件中存储std::vector
时,当我尝试向后推加载的矢量时遇到了Exception thrown: read access violation.
异常,但是仅在调试模式下。
此最小示例代码(由@sehe编写)是从https://stackoverflow.com/a/29602884/2741329中检索到的,它在调试模式上的MSVC14上崩溃,并且执行了多次:
#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());
}
编辑:
这是Visual Studio错误消息:
在这里发生异常:
这是调用堆栈(点击图片放大):
答案 0 :(得分:1)
disable MSVC debug iterators令人振奋。
我不确定如何执行此操作(因为迭代器没有持久化?),但是迭代器调试可能会在std::vector
的内存布局内添加原始指针-违反了有关分配器使用的标准库假设。
仅出于此目的在azure上创建VM,并通过以下稍作修改的代码进行了测试,以更好地了解崩溃原因:
#include <boost/interprocess/managed_mapped_file.hpp>
#include <iostream>
namespace bi = boost::interprocess;
int main() {
std::string vecFile = "vector.dat";
//std::remove(vecFile.c_str());
std::cout << __LINE__ << "\n";
{
bi::managed_mapped_file file_vec(bi::open_or_create, vecFile.c_str(), 100000);
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());
std::cout << "size: " << vecptr->size() << "\n";
}
std::cout << __LINE__ << "\n";
{
bi::managed_mapped_file file_vec(bi::open_or_create, vecFile.c_str(), 100000);
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());
std::cout << "size: " << vecptr->size() << "\n";
}
std::cout << __LINE__ << "\n";
}
重现该问题。第一次运行:
后续运行(带有std::remove
行的注释,如下所示):
放置后
#define _ITERATOR_DEBUG_LEVEL 0
位于最上方的并删除vector.dat
文件,因为更改会更改二进制布局:
注意:在您的实际项目中,您可能需要将
#define
放在多个翻译单元中(尤其要考虑stdafx.cpp
)。最好将其包含在项目属性表中,以便将其应用于所有(将来的)翻译单元!