如果指向的区域被移动,则执行 free(ptr)。
你能解释一下上面的行realloc()
吗?此行来自 calloc、malloc、realloc 和 free 的手册页。
我认为这更好地解释了它:
如果在当前位置没有足够的空间来扩展当前块,则分配大小为 size 的新块,并将现有数据从旧块复制到新块的开头。旧块被释放,函数返回一个指向新块的指针。
引用自C 中的 realloc
假设您有以下堆布局。这是一个简化的内存分配器,其中控制信息不会占用堆中的空间
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 处)的内容复制到它。然后它会为您提供这个新块的地址并释放旧块,因为您不再需要它。这就是你问题中的短语的意思。
这种移动缓冲区的操作取决于内存分配策略,但通常情况下,不会移动缓冲区(它通常很昂贵,因为它涉及大量内存副本),如果:
你不能总是在原地增加内存区域。堆中可能没有空间。因此,它不会增加它,而是分配一个全新的内存块并释放旧内存。