brk(),sbrk()和realloc()函数之间的区别

Vis*_*bal 6 c memory

据我所知,函数brk(),sbrk()用于重新分配内存.但是它们与realloc()函数有什么不同?.给我编码示例.

ste*_*hke 7

brksbrk在系统调用时(在内核中实现)malloc,free,realloc是在用户空间的库函数.所以malloc等功能,使用brksbrk内部,但提供额外的功能(见男人(2)有关详细信息brk男人(3)如需详细了解malloc).

brk只通过给内核指向程序可能使用的最大虚拟内存位置的指针,告诉内核程序想要使用多少内存.但是你只有大块内存.

malloc 帮助您将这个巨大的内存块细分为更小的部分.

示例代码在这里没有多大意义,因为brk并且malloc在不同的级别上工作.但你可以想一想如何实现一个非常简单(和非线程安全)的版本,malloc以及free你在那里使用的brk地方:

  1. 我们的原始malloc的基本数据结构是一个链表.
  2. 列表中的每个列表元素包含:
    1. 块的大小
    2. 指向下一个元素的指针
    3. 如果块正在使用中的标志
    4. 如果它是最后一个元素的标志
    5. 具有给定大小的字节数组
  3. 在每次调用中,malloc都会遍历列表并检查每个块
    1. 如果该块被标记为"未使用"
    2. 如果list元素的size字段最多与所需大小一样大
  4. 如果malloc找到这样的块,它将:
    1. 将列表元素标记为已使用
    2. 调整list元素中的size字段
    3. 如果有足够的空间,则在元素后面添加一个list元素,指向列表中的下一个元素(如果适用)
    4. 返回指向它找到的列表元素的字节数组的指针
  5. 如果malloc找不到这样的列表元素,它就会
    1. 调用brk以增加从内核获得的可用内存
    2. 将新元素添加到列表末尾,将大小设置为所需大小
    3. 将此元素标记为使用AND并作为最后一个元素
    4. 返回指向新创建的列表条目的字节数组的指针

正如@BasileStarynkevitch在他的评论中所说,作为替代brk你也可以使用mmap(with fd=-1flags=MAP_PRIVATE|MAP_ANONYMOUS)来保留由交换文件支持的单个内存块.有关mmap的详细信息,请参阅man(2).


Ste*_*mit 5

在操作系统级别(至少在Unix模型中),您的程序有一个很大的内存区域,用于存储程序文本,已初始化和未初始化的数据,以及用于动态分配数据的“堆”。(堆栈是独立的。)您可以使用brk和调整该区域的大小sbrk,但不能重新排列它,它始终是连续的。进行动态内存分配的大多数程序都需要更灵活的功能。

mallocfreerealloc是C库函数,可为您提供更多灵活性。在下面,它们通过调用brk和/或从操作系统获取内存sbrk,但是它们进行了额外的处理,以使您可以分配(a)(b)不同大小的任意数量的块,并且您可以(c)在以下情况下分别返回到池中:您完成了对它们的操作,然后顺便(d)调整了大小。

但是,当您使用将内存返回到池中时free,它通常只是返回到malloc程序将来的调用将使用的池中。内存通常返还给OS。

(很抱歉没有提供任何示例代码;我暂时没有时间这样做。)