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

时间:2015-04-11 16:31:29

标签: c linux memory-management ipc shared-memory

建议/传统的shmat(int id , void * addr,int flg)的第二个参数应为NULL。

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

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

2 个答案:

答案 0 :(得分:3)

它不应该是,除非你希望附加内存覆盖/破坏已存在的内容。您不需要也不想创建任何内存 - shmat()调用本身就是这样做的。 (通过附加到已存在的共享内存段。)

这就是为什么最好让它为空。

答案 1 :(得分:3)

看看下面的图表:

enter image description here

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

如果 addr 来自应用程序的堆栈段,则调用 shmat 将损坏堆栈。最有可能导致程序中的分段错误。 shmat将覆盖堆栈上的变量,这些变量位于低于您给出的参数的地址。

因此,如果你想发送一个地址,你有更好的机会不破坏任何东西如果该地址来自堆。在堆栈的情况下,您可以覆盖驻留在堆中的数据,但您不希望这样。但通常堆空间更“稀疏”地填充。

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

我粘贴了与 shmat 相关的文档:

  

如果shmaddr不是NULL并且在shmflg中指定了SHM_RND,则为attach   发生在等于shmaddr的地址向下舍入到最近   SHMLBA的倍数。否则shmaddr必须是页面对齐的地址   发生附着的时间

因此,即使您为附加共享内存段提供非NULL地址,也必须进行页面对齐。否则它将向下舍入。