除了共享内存的大小之外,还有什么让我无法 reading/writing? (系统 V IPC)

What stops me from reading/writing further than the size of a shared memory? (System V IPC)

我正在做的是:

shmget(shm_key, shm_size, 0666 | IPC_CREAT);(当然还要附加)

并且我已经将大小设置为正好 12 字节,但是当我尝试类似的操作时:

sprintf(shm_ptr, "Imagine about 200-300 characters here\n");

它似乎正常工作,零问题或警告,并检查 that,我试图从一个完全不同的过程中读取它(我 fork 并执行第一个)果然

printf("%s", shm_ptr);

打印该段中的消息,它应该是 12 字节。 System V IPC 是否应该是这样的,并且没有针对该问题的解决方法?如果是这样,为什么要首先设置尺寸?

提前感谢您的时间和回答。

MMU 硬件正在固定页面大小,因此您的虚拟地址 space 以 4 KB 的页面组织。

任何虚拟地址段(甚至来自 SysV IPCMEM 的虚拟地址段)都是该页面大小的倍数。使用sysconf(3) with PAGESIZE or getpagesize(2)获取。

(并且 Linux 也有 "huge pages" 例如 x86 上的 1Mbytes)。

顺便说一句,阅读该过程的 proc(5) and consider using /proc/self/maps or /proc/1234/maps for the process of pid 1234 to query the virtual address space ....

PS。更喜欢使用 shm_overview(7).

没有什么能阻止你,但规范不保证这种情况下的任何特定行为。

实际上,内存区域的实际大小将四舍五入为系统特定的页面大小。这使得访问比请求更多的内存成为可能,但可能会产生后果。例如,内存清理程序可能会将此视为错误。

所有内存映射都是如此,包括使用 mmap 创建的内存映射。

现在,为什么您需要访问超出请求区域的内存?如果您需要更多内存,只需请求更多。让内存清理器不会因意外行为而发疯是一件非常有用的事情。除此之外,我不认为这有任何后果,至少我不能想出任何东西。

编辑: 如果您想在代码中查找访问错误,可以在内存块的末尾放置一个 "guard page"。只需分配额外的一页内存并使用 mprotect 将其访问权限更改为 PROT_NONE。这样,如果您超出映射范围(但不超过 1 页),就会出现段错误。

没有什么能阻止您尝试使用区域外的地址。但也没有什么可以保护您免受可能的后果。

它可能只是表现得好像该区域更大。它可能会出现段错误(或您平台上的任何等效内容)。它可能会覆盖随机堆内存,导致您的程序以不可预知的方式运行异常。它可能会做 任何事情

C 不提供保证您遵守规则的监护人。 Guardians 很昂贵,如果你想要一个,你将不得不自己支付费用(通过编写 guard 代码,并在必要时执行它)。