Ошибка сегментации после mmap () - PullRequest
2 голосов
/ 22 мая 2011

Я хочу поделиться указателем карты в течение 2 процессов.Поэтому я попробовал 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 ]

2 голосов
/ 22 мая 2011

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

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

1 голос
/ 22 мая 2011

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

...