Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ответы по сиаоду.doc
Скачиваний:
18
Добавлен:
27.09.2019
Размер:
136.7 Кб
Скачать

18. Определение аллокаторов.

Аллокатор (allocator) - это объект, отвечающий за распределение памяти для элементов контейнера. С каждым стандартным контейнером связывается аллокатор (его тип передаётся как один из параметров шаблона). Если какому-то алгоритму требуется распределять память для элементов, он обязан делать это через аллокатор. В этом случае можно быть уверенным, что распределённые объекты будут уничтожены правильно.

В состав STL входит стандартный класс allocator (описан в файле xmemory). Именно его по умолчанию используют все контейнеры, реализованные в STL. Однако пользователь может реализовать собственный класс. Необходимость в этом возникает очень редко, но иногда это можно сделать из соображений эффективности или в отладочных целях.

Линейный аллокатор, по существу, предполагает отсутствие мелочного освобождения выделенных ресурсов памяти и линейным способом выделяет куски памяти один за другим из фиксированного пула. Смотрите на картинку.

Стековый аллокатор.

 С каждым куском памяти, выделенным нашим стековым аллокатором будет опционально проассоциирован указатель на состояние стекового аллокатора непосредственно перед аллоцированием. Это означает, что если мы восстановим это состояние аллокатора (путем изменения его смещения) мы фактически 'освободим' память, которую можно будет повторно использовать. Это показано на диаграмме ниже.

Двусторонний стек.

Он похож на стековый аллокатор, за исключением того, что в нём два стека, из которых один растёт из нижней части буфера вверх, а другой растёт из верхней части буфера вниз. Смотрите картинку: Где это можно использовать? Хорошим примером была бы любая ситуация, где у вас есть данные схожего типа, но с совершенно разным временем жизни, или если бы у вас были данные, которые были бы тесно связаны и должны быть размещены в одной и той же области памяти, но имеют разный размер. Следует отметить, что место, где встретятся смещения двух стеков, не фиксировано. В частности, стеки не должны обязательно занимать половину буфера каждый. Нижний стек может вырастать до очень больших размеров, а верхний быть меньше, и наоборот. Для того, чтоб использовать буфер памяти наилучшим образом, эта дополнительная гибкость может быть иногда необходима.

Пуловый аллокатор, про который я сейчас буду рассказывать, предназначен для работы с данными одинакового типа или размера. Он делит подконтрольный ему буфер памяти на сегменты одинакового размера, а затем позволяет клиенту по его желанию выделять и освобождать эти куски (см. диаграмму ниже). Для этого он должен постоянно отслеживать свободные сегменты, и мне известны несколько способов реализации этого. Я лично избегаю реализаций, использующих стек индексов (или указателей) на свободные сегменты, из-за того что им нужно дополнительное место, что часто может быть непозволительно, но они вообще есть. Реализация, про которую я здесь расскажу, не требует дополнительного места для управления свободными сегментами в пуле. На самом деле, в служебной структуре данных этого аллокатора есть всего два поля, что делает его самым маленьким из всех аллокаторов, описанных в этой заметке.

Часто память, выделяемая в ходе выполнения задачи является временной и сохраняется только на время жизни одного кадра. Для борьбы с неприятными последствиями фрагментации в системах с ограниченной памятью важно использовать эту информацию и размещать память такого рода в отдельных буферах.