了解进程内存的 shmat 和附件?

Understand shmat and attachment to the process memory?

recommended/conventional shmat(int id , void * addr,int flg) 的第二个参数应该是 NULL。

但是如果我想给它一个特定的地址(void* addr),那个地址应该来自堆栈还是堆?

我的意思是我是否必须 malloc() 然后将该地址传递给 shmat,或者我可以声明 void * adrr(或 char * addr)并将其传递给 shmat。

也不应该,除非您想要附加内存到overlay/destroy已经存在的内存。您不需要也不想创建任何内存 - shmat() 调用会自行完成。 (通过附加到一个已经存在的共享内存段。)

这就是为什么最好将其保留为 NULL 的原因。

请看下图:

如果addr为NULL,系统选择第一个可用地址而不破坏BSS段。很可能会在堆中。所以你不需要分配。

如果 addr 来自您应用程序的堆栈段,调用 shmat 将破坏堆栈。这很可能会导致您的程序出现分段错误。 shmat 将覆盖堆栈中位于低于您作为参数提供的地址的变量。

因此,如果您想发送一个地址,如果该地址来自堆,则您有更好的机会不破坏任何东西。在堆栈的情况下 您可以覆盖驻留在堆中的数据 而您不希望这样。但通常堆 space 被填充得更多 "sparsely".

如果实在不想使用NULL,可以在堆上分配一些内存,并将指针指向刚分配的内存。确保分配正确的尺寸。

我贴了shmat相关的文档:

If shmaddr isn't NULL and SHM_RND is specified in shmflg, the attach occurs at the address equal to shmaddr rounded down to the nearest multiple of SHMLBA. Otherwise shmaddr must be a page-aligned address at which the attach occurs

所以即使你给出一个非空地址来附加共享内存段,它也必须是页面对齐的。否则向下舍入。