我需要找到一种使用mmap而不是malloc的方法。这怎么可能?(我不是只使用libc系统调用)是的,brk()是可能的。我使用了sbrk(),但意识到它不是sys调用。。。(x86内联组件)
我环顾四周,看到了这样一个问题:如何使用mmap在堆中分配内存?但这对我没有帮助,因为我有一个segfault。
基本上,我只想创建3块内存来存储字符。
比如
char * x = malloc(1000);
char * y = malloc(2000);
char * z = malloc(3000);
这怎么可能与mmap和如何释放它以后与munmap?
您仔细阅读mmap(2)手册页了吗?我建议你读几遍。
请注意,您只能要求内核[通过mmap
等..]管理与页面大小sysconf(_SC_PAGE_SIZE)
对齐的内存,CCD_2通常为4096字节(我在回答中假设是这样)。
然后你可以做:
size_t page_size = sysconf(_SC_PAGE_SIZE);
assert (page_size == 4096); // otherwise this code is wrong
// 1000 bytes fit into 1*4096
char *x = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS, -1, (off_t)0);
if (x == MMAP_FAILED) perror("mmap x"), exit (EXIT_FAILURE);
// 2000 bytes fit into 1*4096
char *y = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS, -1, (off_t)0);
if (y == MMAP_FAILED) perror("mmap y"), exit (EXIT_FAILURE);
稍后要释放内存,请使用
if (munmap(x, page_size))
perror("munmap x"), exit(EXIT_FAILURE);
etc
如果您想分配5K字节,您需要两个页面(因为5K字节<2*4096和5K字节>1*4096),即mmap(NULL, 2*page_size,
。。。
实际上,您所有的x
、y
、z
只占用8000字节,可以容纳两页,而不是三页。。。但那时你只能把那段记忆放在一起。
请注意,mmap
是一个可能非常昂贵的系统调用。malloc
实现注意避免过于频繁地调用它,这就是为什么它们管理以前的free
-d区域,以便以后(在以后的malloc
-s中)在没有任何系统调用的情况下重用它们。在实践中,大多数malloc
实现管理不同的大分配(例如,超过1兆字节),这些分配通常在malloc
时为mmap
,在free
时为munmap
。。。。你可以学习一些malloc
的源代码。MUSL Libc的可能比Glibc malloc
更容易阅读。
顺便说一句,文件/proc/1234/maps
显示了pid 1234进程的内存映射。也可以在终端中尝试cat /proc/self/maps
,它显示了该cat
进程的内存映射。
您可以调用mmap
在x86 asm中使用以下内容进行匿名映射:
mov eax, 192 ; mmap
xor ebx, ebx ; addr = NULL
mov ecx, 4096 ; len = 4096
mov edx, $7 ; prot = PROT_READ|PROT_WRITE|PROT_EXEC
mov esi, $22 ; flags = MAP_PRIVATE|MAP_ANONYMOUS
mov edi, -1 ; fd = -1 (Ignored for MAP_ANONYMOUS)
xor ebp, ebp ; offset = 0 (4096*0) (Ignored for MAP_ANONYMOUS)
int $80 ; make call (There are other ways to do this too)