c - mmap 替代 malloc

标签 c assembly x86 malloc mmap

我需要找到一种使用 mmap 而不是 malloc 的方法。这怎么可能? (我不是只使用 libc 系统调用)是的,brk() 是可能的。我使用了 sbrk() 但意识到它不是系统调用...(x86 内联汇编)

我环顾四周,看到了这个:How to use mmap to allocate a memory in heap?但这对我没有帮助,因为我遇到了段错误。

基本上,我只想创建 3 个用于存储字符的内存板。

说,

char * x = malloc(1000);
char * y = malloc(2000);
char * z = malloc(3000);

这如何通过 mmap 实现以及稍后如何使用 munmap 释放它?

最佳答案

您是否仔细阅读了 mmap(2)手册页?我建议多读几遍。

请注意,您只能要求内核 [通过 mmap 等...] 管理与页面大小 sysconf(_SC_PAGE_SIZE) 对齐和倍数的内存,这是通常是 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);

等等

如果你想分配 5Kbytes,你需要两个页面(因为 5Kbytes < 2*4096 和 5Kbytes > 1*4096)即 mmap(NULL, 2*page_size, ...

实际上,您所有的 xyz 只需要 8000 字节,可以放入两页,而不是三页。 . 但是你只能 munmap 那个内存在一起。

请注意,mmap 是一个系统调用,可能会非常昂贵。 malloc 实现注意避免过于频繁地调用它,这就是为什么他们管理以前的 free-d 区域以便以后重用它们(进一步 malloc -s) 没有任何系统调用。在实践中,大多数 malloc 实现管理不同的大分配(例如超过一兆字节),这些分配通常在 malloc 处被 mmap 编辑>munmap-ed at free time....你可以研究一些malloc的源代码。来自 MUSL Libc 的那个可能比 Glibc malloc 更容易阅读。

顺便说一句,文件 /proc/1234/maps 显示了 pid 1234 进程的内存映射。也可以尝试 cat/proc/self/maps终端,它显示该 cat 进程的内存映射。

关于c - mmap 替代 malloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14786484/

相关文章:

assembly - s/360 程序集 : how to implement a call stack

assembly - 为什么我不能保存 rip 的值?

c - 使用memcpy时重叠的含义

c - 如何在 Linux (ubuntu 16.04) 上运行 OpenCL 程序?

linux - 好的 Linux 汇编语言调试器?

optimization - 使用AVX2指令选择性地对列表元素进行异或

c - 堆栈何时增长?操作系统如何知道何时增长堆栈?

c++ - 获取错误代码 C2228 : left of '._Ptr' must have class/struct/union

c - 将 char 减去 '0' 以转换为 int 不好的做法吗?

debugging - GDB还是Radare2?