使用mmap和malloc在同一程序中分配内存是否安全?

时间:2019-10-04 07:48:57

标签: c malloc mmap

到目前为止,我的理解如下:

  1. malloc内部使用sbrkbrk通过增加堆的顶部来分配内存。
  2. mmap以页面形式分配内存。

现在,假设sbrk/malloc的当前顶部是0x001000。我使用mmap分配了一个4KB的页面,该页面分配在0x0020000上。后来,如果我多次使用malloc,因此必须增加sbrk top。那么,如果顶部达到0x002000怎么办?

因此,如果有人可以澄清以下内容,那就太好了。

  1. 以上情况是否可能?
  2. 如果没有,请指出我对mallocmmap的理解存在缺陷。
  3. 如果是,我认为以这种方式使用它是不安全的。那么,还有其他方法可以安全地使用两者吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

  1. malloc通常今天不会以这种方式实现... malloc在旧的实现中使用了sbrk(2),而扩展数据段是要求系统提供更多虚拟内存的唯一方法。较新的系统将使用mmap(2)(如果可用),因为当虚拟空间足够大时,它们会提供更大的灵活性(每个mmap块都作为请求它的进程的新数据段进行管理)。 sbrk(2)像堆栈一样扩展和缩小数据段。...所以您必须谨慎使用sbrk(2),以防将其与sbrk实现的混合使用malloc。 malloc的操作方式通常不允许您在混用调用的情况下返回通过sbrk(2)获得的任何内存...因此,只能使用它安全地增长数据段。

  2. sbrk(2)还在页面中分配内存。由于出现了分页的虚拟内存,因此几乎所有操作系统都可以使用。以页为单位进行分配。较新的系统甚至有一个以上的页面大小(例如4Kb和2Mb大小),因此您可以从中受益,具体取决于应用程序。

  3. 随着64位系统得到越来越多的使用,分配足够大的地址空间以允许两种机制一起生活是没有问题的。这对于多堆malloc实现是一个优势,因为内存是独立分配和释放的,并且永远不会按LIFO分配顺序进行。

Malloc使用不同的方法来分配内存,但是实现通常尝试不干扰用户sbrk(2)的使用。您必须要小心,也就是说,如果在malloc(3) malloc系统中将sbrk(2)调用与sbrk(2)混合在一起。则冒着sbrk(2)遍历经过malloc调整的数据段并破坏malloc内部数据结构的风险。如果您正在使用malloc的sbrk(2)实现,则最好不要自己使用sbrk(2)

最后,要回答您的问题,mmap(2)malloc(3)那样分配内存,因此malloc不会(也不必)知道您为{{ 1}}。