调试模式下内存映射向量的读取访问冲突 [英] Read access violation for memory mapped vector in debug mode

查看:20
本文介绍了调试模式下内存映射向量的读取访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当尝试使用 boost::interprocessstd::vector 存储在内存映射文件中时,我收到异常 Exception throw: read访问冲突.当我尝试推回加载的向量时,但仅在调试模式下.

这个最小的示例代码(由@sehe 编写)取自

这里是异常发生的地方:

这是调用堆栈(点击图片放大):

解决方案

作为一个脑波,

后续运行(带有注释的 std::remove 行,如图所示):

变通方法演示

放置后

#define _ITERATOR_DEBUG_LEVEL 0

在最顶部并删除 vector.dat 文件,因为更改改变了二进制布局:

<块引用>

注意:在您的实际项目中,您可能需要将 #define 放在多个翻译单元中(尤其要考虑 stdafx.cpp).将它包含在项目属性表中可能会好得多,以便它适用于所有(未来)翻译单元!

While attempting to use boost::interprocess for storing a std::vector in a memory mapped file, I am getting the exception Exception thrown: read access violation. when I try to push back on a loaded vector, but only in debug mode.

This minimal example code (written by @sehe) is retrieved from https://stackoverflow.com/a/29602884/2741329, and it crashes on MSVC14 in debug mode and executed more than once:

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

EDIT:

This is the Visual Studio error message:

Here the point where the exception happens:

This is the call stack (click on the pic to enlarge it):

解决方案

As a brainwave, disable MSVC debug iterators.

I'm not sure how (because iterators aren't persisted?) but somehow iterator debugging might add raw pointers inside the memory layout of the std::vector - violating standard library assumptions about allocator use.

Test Results

Creating a VM on azure just for the purpose, tested with the following slightly modified code to better understand the crash reasons:

#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";
}

Reproduces the issue. First run:

Subsequent run (with the std::remove line commented as shown):

WORKAROUND DEMO

After putting

#define _ITERATOR_DEBUG_LEVEL 0

at the very top AND REMOVING THE vector.dat file because the change alters binary layout:

Note: in your actual project you may require putting that #define in multiple translation units (especially consider stdafx.cpp). It's probably much better to include it in the project property sheets so it applies to all (future) translation units!

这篇关于调试模式下内存映射向量的读取访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆