使用mmap映射共享内存的大小大于ftruncate设置的大小

时间:2019-03-01 09:51:14

标签: c ubuntu posix shared-memory

根据以下消息来源,我有几个问题:

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>

int g;
int main(void) {
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int)); // set size by sizeof(int)
    int *p1 = mmap(NULL, 10*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0); //now map  10*sizeof(int).
    if (p1== MAP_FAILED) {
        printf("*****************error");
    }
    *p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
    if (p1== MAP_FAILED) {
        printf("*****************error");
    }

    *p1=89;

    return g;
}

问题1: 为什么我在将size设置为size_of(int)然后映射10 * size_of(int)时看不到任何错误

问题2: 在这里创建了多少个共享内存实例?我的意思是只创建了一个共享内存或两个,我做了两次mmap?

谢谢

1 个答案:

答案 0 :(得分:1)

给出代码

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>

int g;
int main(void) {
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int)); // set size by sizeof(int)
    int *p1 = mmap(NULL, 10*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0); //now map  10*sizeof(int).
    *p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
    if (!p1){
        printf("*****************error");
    }
    *p1 = g;
    *p1=89;

    return g;
}
  

问题1:为什么在将size设置为size_of(int)然后映射10 * size_of(int)时为什么看不到任何错误

因为您没有检查mmap()的返回值,所以您不知道是否发生错误。通过再次使用{p>立即调用mmap()

*p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);

您会屏蔽掉第一次mmap()调用中的所有潜在错误,并且还会泄漏所有已成功分配的内存。

  

问题2:在此处创建了多少个共享内存实例?我的意思是只创建了一个共享内存或两个,我做了两次mmap?

如果第一个调用成功,您将映射两个内存段。如果失败,则仅在第二次成功的情况下映射一个。

如果第一次调用成功,则泄漏了内存。

请注意,如果您尝试在用mmap()设置的文件大小的末尾写入ftruncate()的段,则不会导致文件增长。根据{{​​3}}:

  

请注意,超出对象末端的引用不会扩展对象,因为大多数虚拟内存硬件无法精确确定新末端。而是可以通过ftruncate()直接控制大小。

在Linux上,尝试访问已映射文件末尾的mmap()数据可能会导致您的过程the POSIX mmap() documentation