我想在两个过程中分享一个地图的指针。 所以我试了mmap。 我在一个进程中testing了mmap。 这是我的代码:
#include <vector> #include <iostream> #include <sys/mman.h> #include <unistd.h> #include <cstdlib> #include <stdio.h> #include <map> using namespace std; int main(int argc, char *argv[]) { map<string,string> a, *b; b = (map<string,string> *)mmap(&a,sizeof(map<string,string>), PROT_READ|PROT_WRITE,MAP_ANON|MAP_SHARED,-1,0); b->insert(map<string,string>::value_type("a","b")); //error cout << b->size() << endl; }
当它运行到b->insert()
,出现分段错误。 如果我删除b->insert()
,没有错误(仍然有b->size
)。 我的代码有什么问题?
你正在用mmap
分配新的内存(为什么?似乎是一个坏主意…),但你没有初始化你的map
。 使用“放置新的”来初始化它。
void *p = mmap(....); if (p == MAP_FAILED) abort(); map<string,string> *b = new(p) map<string,string>(); b->insert(...);
但是我怀疑有些东西是非常错误的, mmap
真的不应该被卷入这里。
编辑:从评论,这听起来像你想在两个进程之间共享内存。 共享内存可能远远超出您当前的技能水平。 您通常不能在共享内存段中放置std::map
对象,因为它将包含对堆内部对象的引用,除非您可以创建自定义分配器来仅在共享内存段内创建子对象, 。
您可以使用shm_open
创建共享内存对象,可以使用ftruncate
更改其大小,并可以使用mmap
将其映射到内存中。 shm_open
同名的不同进程会得到相同的对象,共享对象描述符也可以像进程文件描述符一样在进程之间传递。
尽管它的名字, mmap()
与std::map
没有任何关系。 当你使用mmap()
,你可以访问没有结构的原始内存块。 因为在STL对象内部有与mmap()
不兼容的内部指针,所以不能直接存储std::map
之类的STL对象。
当您使用mmap()
将同一块内存映射到两个不同的进程时,该块甚至可能不会出现在内存中的相同地址处。 定义要存储在共享内存中的数据格式时,必须考虑到这一点。