在对象构造函数中打开Boost Interprocess段引发的访问冲突问题
问题原因及解决方案
核心问题原因
你遇到的访问违例本质是共享内存映射被提前卸载导致悬空指针:
Communication构造函数中创建的managed_shared_memory segment是局部变量,构造函数执行完毕后该对象会被销毁。Boost Interprocess的managed_shared_memory是RAII类型,销毁时会自动解除当前进程对共享内存的映射。- 你保存的
map指针指向共享内存中的地址,一旦映射被卸载,这个地址就变成无效的悬空指针,后续调用addData访问map时必然触发内存访问错误。
可行的修正方案
完全可以按你最初的思路使用Boost Interprocess,只需调整Communication类的结构,让managed_shared_memory的生命周期覆盖map的整个使用周期:
// 子进程代码(注入DLL的进程) class Communication{ managed_shared_memory segment; // 作为类成员,维持共享内存映射 Int_Vector_Map* map; public: Communication() : segment(open_only, "Shared") { // 初始化列表中构造segment map = segment.find<Int_Vector_Map>("Map").first; } void addData(int _key, int _value){ if(map->size() == 0 || map->find(_key) == map->end()){ Int_Allocator alloc = segment.get_segment_manager(); // 使用类成员的segment获取分配器 map->insert(Int_Vector_Map_Type(_key, Int_Vector(alloc))); } map->at(_key).push_back(_value); } };
关键修改点
- 将
managed_shared_memory改为Communication类的成员变量,使其生命周期与Communication对象一致,只要对象存在,共享内存映射就会保持有效。 - 在构造函数初始化列表中创建
segment,避免局部临时对象的销毁问题。 addData中直接使用类成员的segment获取分配器,无需重复打开共享内存。
额外注意事项
- 多进程访问共享内存必须添加同步机制(比如
interprocess_mutex),否则多个进程同时写入map会引发数据竞争,导致未定义行为。当前代码缺少同步,即使修复悬空指针问题,也可能出现数据损坏。 - 确保父进程创建的共享内存未被提前销毁,否则子进程访问时同样会出错。
内容的提问来源于stack exchange,提问作者Moritz Perschke
相关产品推荐
相关产品推荐

