Допустим, у вас есть следующие макеты кучи. Это упрощенный распределитель памяти, в котором управляющая информация
не занимает место в куче.
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). Затем он дает вам адрес этого нового блока и освобождает старый блок , поскольку он вам больше не нужен. Вот что означает фраза в вашем вопросе.
Это действие перемещения буферов зависит от стратегии выделения памяти, но, как правило, буфер не будет перемещаться (это часто дорого, поскольку включает в себя массовую копию памяти), если либо:
- после него есть свободное пространство, которое, наряду с текущим пространством, может удовлетворить перераспределение; или
- Вы уменьшаете размер.