2016-03-29 4 views
2

Если у меня один сегмент разделяемой памяти размером 1024, как я могу объединить три области его размера? Я попробовал следующее, но получил ошибку seg. Я думаю, что что-то не выровнено правильно, но я не могу изолировать себя.Как я могу разделить одну общую память на 3-х различных указателей mmap в C?

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

ответ

1

As Adam Martin notes, смещения должны быть кратными размеру страницы. Но вы, вероятно, не нужны три отдельных mmap с, а может просто mmap один раз и использовать указатели на разные смещения этого единого отображения:

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

Просто помните, чтобы вызвать только munmap на addr0 (в этот момент все три указателя становятся недействительными). В качестве альтернативы, вы mmap из одной и той же начальной точки в три раза, а также настроить каждый указатель по отдельности (что позволит вам munmap каждое значение по отдельности, просто убедитесь, что сделать это на оригинальном указателю, а не скорректированный указатель):

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

Ваше смещение (последний аргумент mmap) должен быть кратен размеру страницы man. Также fruncate должен быть ftruncate, хотя я предполагаю, что вы представили, что опечатка копирует это, иначе ваш код не должен компилироваться.