mmap() 后出现分段错误

发布于 2024-11-09 03:40:40 字数 751 浏览 0 评论 0原文

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

I wanna share a pointer of map during 2 processes. So I tried mmap. I tested mmap in a single process. Here is my code:

#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;
}

when it runs to b->insert(), Segmentation fault occured. If I remove b->insert(), there is no error (still have b->size). What's the problem with my code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暖心男生 2024-11-16 03:40:40

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

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

Despite its name, mmap() has nothing to do with std::map. When you use mmap(), you get access to a raw block of memory with no structure. You cannot directly store STL objects like std::map in that block, because there are internal pointers inside the STL objects that are not compatible with mmap().

When you use mmap() to map the same block of memory into two different processes, that block may not even appear at the same address in memory. You must take this into account when defining the format of data you will store in the shared memory.

Saygoodbye 2024-11-16 03:40:40

您正在使用 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同名的不同进程会得到同一个对象,共享对象描述符也可以像文件描述符一样在进程之间传递。

You are allocating new memory with mmap (why? seems like a bad idea...) but you are not initializing your map. Use "placement new" to initialize it.

void *p = mmap(....);
if (p == MAP_FAILED)
    abort();
map<string,string> *b = new(p) map<string,string>();
b->insert(...);

But I suspect something is terribly wrong, and mmap really shouldn't be involved here...

Edit: From the comments, it sounds like you want to share memory between two processes. Shared memory is probably far beyond your current skill level. You cannot normally place a std::map object inside a shared memory segment, because it will contain references to internal objects on the heap, which will not be shared, unless you can create a custom allocator to only create subobjects inside the shared memory segment.

You can create a shared memory object with shm_open, you can change its size with ftruncate, and you can map it into memory with mmap. Different processes that shm_open the same name will get the same object, and the shared object descriptor can also be passed between processes just like file descriptors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文