建议/传统的shmat(int id , void * addr,int flg)
的第二个参数应为NULL。
但是如果我想给它一个特定的地址(void* addr
),该地址应该来自堆栈还是堆?
我的意思是我必须使用malloc()然后将该地址传递给shmat,或者我可以声明void * adrr(或char * addr)并将其传递给shmat。
答案 0 :(得分:3)
它不应该是,除非你希望附加内存覆盖/破坏已存在的内容。您不需要也不想创建任何内存 - shmat()调用本身就是这样做的。 (通过附加到已存在的共享内存段。)
这就是为什么最好让它为空。
答案 1 :(得分:3)
看看下面的图表:
如果 addr 为NULL,系统会选择第一个可用地址而不会破坏BSS段。最有可能是在堆中。所以你不需要分配。
如果 addr 来自应用程序的堆栈段,则调用 shmat 将损坏堆栈。最有可能导致程序中的分段错误。 shmat将覆盖堆栈上的变量,这些变量位于低于您给出的参数的地址。
因此,如果你想发送一个地址,你有更好的机会不破坏任何东西如果该地址来自堆。在堆栈的情况下,您可以覆盖驻留在堆中的数据,但您不希望这样。但通常堆空间更“稀疏”地填充。
如果你真的不想使用NULL,你可以在堆上分配一些内存,并将指针指向刚刚分配的内存。确保分配正确的大小。
我粘贴了与 shmat 相关的文档:
如果shmaddr不是NULL并且在shmflg中指定了SHM_RND,则为attach 发生在等于shmaddr的地址向下舍入到最近 SHMLBA的倍数。否则shmaddr必须是页面对齐的地址 发生附着的时间
因此,即使您为附加共享内存段提供非NULL地址,也必须进行页面对齐。否则它将向下舍入。