Ошибка сегментации после 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). В чем проблема с моим кодом?


person Ace    schedule 22.05.2011    source источник
comment
Даже если вы сможете использовать карту, выделенную в mmap, она не может быть разделена между процессами. STL не хранит все элементы внутри b, он использует указатели и классические распределители, работающие через new/delete или malloc/free. Если вам действительно нужно поделиться какой-то структурой данных, вам нужно определить и реализовать ее самостоятельно.   -  person osgx    schedule 22.05.2011


Ответы (2)


Вы выделяете новую память с помощью 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 имеют одно и то же имя, получат один и тот же объект, и дескриптор общего объекта также может передаваться между процессами так же, как файловые дескрипторы.

person Dietrich Epp    schedule 22.05.2011
comment
Я просто хочу поделиться картой между несколькими процессами, есть ли лучший способ? - person Ace; 22.05.2011

Несмотря на свое название, mmap() не имеет ничего общего с std::map. Когда вы используете mmap(), вы получаете доступ к необработанному блоку памяти без структуры. Вы не можете напрямую хранить объекты STL, такие как std::map, в этом блоке, потому что внутри объектов STL есть внутренние указатели, несовместимые с mmap().

Когда вы используете mmap() для сопоставления одного и того же блока памяти с двумя разными процессами, этот блок может даже не отображаться по одному и тому же адресу в памяти. Вы должны принять это во внимание при определении формата данных, которые вы будете хранить в общей памяти.

person Greg Hewgill    schedule 22.05.2011