c - mmap substitute for malloc



我需要找到一种使用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,。。。

实际上,您所有的xyz只占用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)

相关内容

  • 没有找到相关文章

最新更新