4

如果指向的区域被移动,则执行 free(ptr)。

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

4

3 回答 3

16

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

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

引用自C 中的 realloc

于 2009-04-25T18:08:35.180 回答
11

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

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

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

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

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

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

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

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

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

  • 其后有空闲空间,可以与当前空间一起满足重新分配;或者
  • 你正在缩小尺寸。
于 2009-04-26T12:58:32.623 回答
2

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

于 2009-04-25T18:09:51.650 回答