使用realloc调整缓冲区大小

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

你能解释一下关于realloc()的上述内容吗? 这一行来自calloc,malloc,realloc和free的手册页。

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

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

引用来自C中的realloc

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

 Addr AB +------------+ +------------+ 1000 | your space | | your space | +------------+ +------------+ 2000 | free space | | used space | | | +------------+ 3000 | | | free space | | | | | 4000 | | | | +------------+ +------------+ 

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

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

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

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

 Addr AB +------------+ +------------+ 1000 | your space | | free space | | | +------------+ 2000 | | | used space | +------------+ +------------+ 3000 | free space | | your space | | | | | 4000 | | | | +------------+ +------------+ 

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

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

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

你不能总是只是原地增长记忆区域。 堆中可能没有空间。 因此,它不会增长它,而是分配一个全新的内存块并释放旧内存。