CompSci-PVT CompSci-PVT - 2 months ago 19
C Question

How can I split one shared memory into 3 different sized mmap pointers in C?

If I have one shared memory segment of size 1024, how do I mmap three different sized regions of it? I tried the following, but got a seg fault. I think something is not aligned correctly but I can't seem to isolate where.

fd = shm_open(NAME, FLAGS, MODE);
ftruncate(fd, 1024);
addr0 = mmap(NULL, 50, PROTS, FLAGS, fd, 0);
addr1 = mmap(NULL, 100, PROTS, FLAGS, fd, 50);
addr2 = mmap(NULL, 874, PROTS, FLAGS, fd, 150);

Answer

As Adam Martin notes, offsets must be multiples of the page size. But you probably don't need three separate mmaps, and could just mmap once and use pointers to different offsets of that single mapping:

fd = shm_open(NAME, FLAGS, MODE);
ftruncate(fd, 1024);
addr0 = mmap(NULL, 1024, PROTS, FLAGS, fd, 0);
addr1 = (void*)((char*)addr0 + 50);
addr2 = (void*)((char*)addr1 + 100);

Just remember to only call munmap on addr0 (at which point all three pointers become invalid). Alternatively, you mmap from the same start point three times, and adjust each pointer individually (which would allow you to munmap each value individually, just make sure to do so on the original pointer, not the adjusted pointer):

fd = shm_open(NAME, FLAGS, MODE);
ftruncate(fd, 1024);
addr0 = mmap(NULL, 50, PROTS, FLAGS, fd, 0);
char *const baseaddr1 = mmap(NULL, 150, PROTS, FLAGS, fd, 0);
char *const baseaddr2 = mmap(NULL, 1024, PROTS, FLAGS, fd, 0);
addr1 = (void*)(baseaddr1 + 50);
addr2 = (void*)(baseaddr2 + 150);
Comments