mmap()后的分段错误

时间:2011-05-22 10:13:37

标签: c++ linux unix mmap

我想在两个过程中分享一个地图指针。所以我尝试了mmap。我在一个过程中测试了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)。我的代码有什么问题?

2 个答案:

答案 0 :(得分:2)

尽管名称如此,mmap()std::map无关。使用mmap()时,可以访问没有结构的原始内存块。您不能在该块中直接存储std::map之类的STL对象,因为STL对象内部存在与mmap()不兼容的内部指针。

当您使用mmap()将同一块内存映射到两个不同的进程时,该块甚至可能不会出现在内存中的同一地址。在定义将存储在共享内存中的数据格式时,必须考虑到这一点。

答案 1 :(得分:1)

您正在使用mmap分配新内存(为什么?似乎是一个坏主意......)但您没有初始化map。使用“placement new”初始化它。

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同名的不同进程将获得相同的对象,共享对象描述符也可以在进程之间传递,就像文件描述符一样。

相关问题