Память
Системы распределения памяти необходимы для того, чтобы выделять место под программные объекты и освобождать ранее выделенную память, когда минует надобность в ней. В языке С эту задачу решали с помощью системных вызовов malloc, calloc и free. В языке C++ тоже можно пользоваться этими же функциями, однако гораздо удобнее использовать конструкции языка new и delete, которые, кроме обеспечения распределения памяти, позволяют еще и вызвать конструкторы и деструктор объектов. В большинстве случаев вполне достаточно иметь встроенные механизмы работы этих примитивов, но в языке разрешается переопределять алгоритмы работы этих операторов для более эффективного решения той или иной задачи.
В разд. 2.2 описывалась цифровая сортировка элементов массива (ключей), при которой требовалось многократно строить и уничтожать списки элементов массива. Конечно, можно было бы при добавлении каждого элемента в список отводить память под него с помощью оператора new, а когда элемент возвращался в массив освобождать отведенную под него память с помощью оператора delete. Однако такая реализация алгоритма имела бы очень небольшую скорость работы из-за частых вызовов сложных системных механизмов распределения памяти, да и количество фактически затрачиваемой памяти тоже было бы довольно большим, поскольку система всегда резервирует некоторое дополнительное количество памяти при каждом вызове оператора new для своих нужд.
Для реализации цифровой сортировки мы построили небольшую узкоспециализированную систему распределения памяти, которая отводила память под элементы списков внутри некоторого пула памяти. Обращение к встроенной системе распределения памяти при этом производилось только один раз, когда надо было отвести память под весь пул. В дальнейшем вся работа с элементами списков производилась нашей специализированной системой распределения памяти, и лишь в конце сортировки деструктор пула памяти вновь обращался к системе программирования для возврата всей заказанной памяти в систему.
В этой главе мы рассмотрим несколько способов организации систем распределения памяти, которые позволят нам самим программировать различные способы отведения и освобождения памяти в соответствии с потребностями решаемой задачи. Кроме того, мы рассмотрим, как язык C++ позволяет соединить удобство пользования операторами new и delete с преимуществами, которые может предоставить система распределения памяти, реализованная программистом.