使用realloc调整缓冲区大小

maw*_*wia 4 c realloc

如果指向的区域被移动,则完成自由(ptr).

你能解释一下上面的一行realloc()吗?这一行来自calloc,malloc,realloc和free的手册页.

Nav*_*een 15

我认为这更好地解释了它:

如果不存在足够的空间来扩展当前块的当前位置,则分配大小的新块,并将现有数据从旧块复制到新块的开头.释放旧块,函数返回指向新块的指针.

引用来自C中的realloc


pax*_*blo 11

假设您有以下堆布局.这是一个简化的内存分配器,其中控制信息不会占用堆中的空间

Addr       A                   B
     +------------+      +------------+
1000 | your space |      | your space |
     +------------+      +------------+
2000 | free space |      | used space |          
     |            |      +------------+
3000 |            |      | free space |
     |            |      |            |
4000 |            |      |            |
     +------------+      +------------+
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,您在地址1000处分配了1000个字节.但是,在情况B中,紧接着是为某些其他目的分配的内存.

让我们来看看当你想要将内存重新分配到2000字节时会发生什么.

在情况A中,这很容易,它只是按照下图扩展您的分配.

但是,在情况B中,它并不那么容易.紧随您的块之后的内存正在使用中,因此没有足够的空间来扩展您的分配,并且您需要连续的内存.这是两种情况的最终位置:

Addr       A                   B
     +------------+      +------------+
1000 | your space |      | free space |
     |            |      +------------+
2000 |            |      | used space |
     +------------+      +------------+
3000 | free space |      | your space |
     |            |      |            |
4000 |            |      |            |
     +------------+      +------------+
Run Code Online (Sandbox Code Playgroud)

对于情况B,分配器找到块(3000),其您所需的扩展足够大,并复制你的当前块的内容(1000)给它.然后它会为您提供此新块的地址并释放旧块,因为您不再需要它.这就是你的问题中的短语意味着什么.

移动缓冲区的动作取决于内存分配策略,但通常情况下,缓冲区不会移动(因为它涉及大容量内存复制,因此通常很昂贵):

  • 之后有自由空间,与当前空间一起,可以满足重新分配; 要么
  • 你正在缩小尺寸.