CompSci-PVT
CompSci-PVT

Reputation: 1403

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);

Upvotes: 2

Views: 1341

Answers (2)

ShadowRanger
ShadowRanger

Reputation: 155323

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);

Upvotes: 1

Adam Martin
Adam Martin

Reputation: 1218

Your offset (last argument to mmap) must be a multiple of page size man. Also fruncate should be ftruncate, though I assume you introduced that typo copying this over, otherwise your code shouldn't compile.

Upvotes: 0

Related Questions