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

时间:2015-06-24 12:33:45

标签: c memory

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

2 个答案:

答案 0 :(得分:7)

brksbrk是系统调用(在内核中实现),而mallocfreerealloc是用户空间中的库函数。因此,malloc等功能在内部使用brksbrk,但提供了其他功能(有关brkman(2)的详细信息,请参阅man(3)了解更多信息有关malloc的详情。)。

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

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

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

  1. 我们的原始malloc的基本数据结构是一个链表。
  2. 列表中的每个列表元素包含:
    1. 块的大小
    2. 指向下一个元素的指针
    3. 块正在使用时的标志
    4. 如果是最后一个元素的标志
    5. 具有给定大小的字节数组
  3. 在每次调用中,malloc都会遍历列表并检查每个块
    1. 如果该块被标记为"未使用"
    2. 如果列表元素的大小字段最多与所需大小一样大
  4. 如果malloc找到这样的块,它将:
    1. 将列表元素标记为已使用
    2. 调整列表元素中的大小字段
    3. 如果有足够的空间,则在元素后面添加一个list元素,指向列表中的下一个元素(如果适用)
    4. 返回指向它找到的列表元素的字节数组的指针
  5. 如果malloc找不到这样的列表元素,它就会
    1. 调用brk以增加从内核获得的可用内存
    2. 将新元素添加到列表末尾,将大小设置为所需大小
    3. 将此元素标记为使用AND并将其作为最后一个元素
    4. 返回指向新创建的列表条目
    5. 的字节数组的指针
  6. 正如@BasileStarynkevitch在评论中所说,作为brk的替代方案,您也可以使用mmapfd=-1flags=MAP_PRIVATE|MAP_ANONYMOUS)来保留由交换文件支持的单个内存块。有关mmap的详细信息,请参阅man(2)

答案 1 :(得分:4)

在操作系统级别(至少在Unix模型中),您的程序有一个大的内存区域用于程序文本,初始化和未初始化的数据,以及"堆",用于动态分配的数据。 (堆栈是分开的。)您可以使用sbrkmalloc调整该区域的大小,但不能重新排列,并且它始终是连续的。绝大多数进行动态内存分配的程序需要更灵活的东西。

freereallocbrk是C库函数,可为您提供更灵活的功能。在下面,他们通过调用sbrk和/或free从操作系统获取内存,但随后他们进行了额外的处理,以便您分配(a)任意数量的(b)不同大小的块,并且您可以(c)当你完成它们时单独返回游泳池并顺便(d)调整大小。

但是当您使用malloc将内存返回到池中时,通常只会回到池中,以后您的程序将来自{{1}}的调用将从中抽取;内存通常返回给操作系统。

(很抱歉没有提供任何示例代码;我现在也没有时间。)