我需要在进程之间使用共享内存,我在这里找到了一个示例代码.首先,我需要学习如何创建共享内存块并在其中存储字符串.为此,我使用以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
void* create_shared_memory(size_t size) {
// Our memory buffer will be readable and writable:
int protection = PROT_READ | PROT_WRITE;
// The buffer will be shared (meaning other processes can access it), but
// anonymous (meaning third-party processes cannot obtain an address for it),
// so only this process and its children will be able to use it:
int visibility = MAP_ANONYMOUS | MAP_SHARED;
// The remaining parameters to `mmap()` are not important for this use case,
// but the manpage for `mmap` explains their purpose.
return mmap(NULL, size, protection, visibility, 0, 0);
}
int main() {
char msg[] = "hello world!";
void* shmem = create_shared_memory(1);
printf("sizeof shmem: %lu\n", sizeof(shmem));
printf("sizeof msg: %lu\n", sizeof(msg));
memcpy(shmem, msg, sizeof(msg));
printf("message: %s\n", shmem);
}
Run Code Online (Sandbox Code Playgroud)
输出:
sizeof shmem: 8
sizeof msg: 13
message: hello world!
Run Code Online (Sandbox Code Playgroud)
在main函数中,我创建了1个字节的共享内存块(shmem)并尝试在其中存储13个字节的信息(char msg[]).当我打印出来时shmem,它会打印整条信息.我期待它,在这种情况下它只打印出1字节的消息"h".或者它可能在编译时给出有关内存大小的错误.
问题是我在这里失踪了吗?或者是否存在实施问题?不memcpy重叠在这里?我很感激任何简短的解释.
提前致谢.
在printf("message: %s\n", shmem);,%s说明者说打印从"开始"的"字符串" shmem.为此,字符串是以空字符结尾的字符序列.因此,printf它将找到的所有字节打印shmem到空字符.要将其限制为最多一个字符,您可以%.1s改为使用,或者可以使用显式打印字符printf("message: %c\n", * (char *) shmem);.
使用时分配内存时mmap,系统以页为单位使用内存.页面大小因系统而异,但通常为512或4096字节,而不是1.标准规范mmap仅保证您提供的字节数.除此之外可能还有其他字节可访问,但您不应该依赖它们.(即使它们似乎暂时可用,当程序暂时从内存中换出时,系统可能无法将它们保存到磁盘,因此当程序返回内存以继续运行时,它们将无法恢复.)
sizeof(shmem)提供shmem指针的大小.因此它提供了指针的大小,在现代系统上通常为4或8个字节.它没有提供shmem指向的东西的大小.
相反,在sizeof(msg),msg是一个数组,而不是一个指针,所以sizeof(msg)确实提供了数组的大小,因为你可能打算.
memcpy(shmem, msg, sizeof(msg));复制13个字节(你的大小msg)shmem.那十三个字节是"hello world!",最后是一个空字符(值0).memcpy除了您传递的长度参数之外,没有任何方法可以知道源或目标的长度.所以它复制sizeof(msg)字节.它并不局限于指向的内存大小shmem.通过正确的长度是你的工作.
要回答有关如果使用的字节多于mmap提供的字符数会发生什么情况的问题,则行为未定义.如果超出页面边界,则程序很可能会崩溃,因为超出该地址的内存未映射.但是您可能会将字节写入内存中您不想要的位置,这可能会导致各种各样的事情发生,因为它可能会损坏程序需要正确执行的代码或数据.
在这种情况下,您没有写入映射内存.你问了13个字节,可能给了4096(或者你系统上的任何一个页面).然后你将这13个字节复制到缓冲区并打印出来.所以一切都"有效".
| 归档时间: |
|
| 查看次数: |
839 次 |
| 最近记录: |