Написание распределения памяти
Фрагмент для распределения памяти в C
Определения памяти 101 - Напишите простой распределитель памяти
void * malloc ( size_t size );
void free ( void * ptr );
Block * merge_blocks ( Block * block );
// the above three will be implemented first later calloc and realloc Определите структуру данных : вам понадобится структура данных, чтобы отслеживать размер и состояние распределения каждого блока. Это может быть простая структура с размером и флагом, указывающий, является ли блок свободным или нет.
Инициализируйте кучу : Когда ваша программа начинается, вам нужно отложить кусок памяти, чтобы выступить в качестве вашей кучи. Это можно сделать с помощью системы mmap() .
Реализовать malloc() : эта функция должна найти бесплатный блок, который достаточно большой, чтобы удовлетворить запрос. Если такой блок не существует, он должен увеличить размер кучи. Как только подходящий блок найден, он должен быть отмечен как выделенный, и его адрес возвращается.
Реализовать free() : Эта функция должна принять указатель на блок памяти, отметьте ее как свободную и потенциально уменьшить размер кучи, если в конце находится Блок Freed.
Реализация realloc() : эта функция должна изменить размер выделенного блока. Это может включать в себя поиск нового блока и копирование старых данных.
Обработка фрагментации : со временем куча может быть фрагментирована со свободными блоками, разбросанными повсюду. Возможно, вы захотите реализовать стратегию дефрагментации кучи, такую как объединение прилегающих свободных блоков.
В контексте распределителя кучи «блоки» относятся к кускам памяти в куче. Вот почему они вам нужны и как они работают:
Почему блоки? : Когда вы управляете памятью, полезно разделить ее на управляемые куски или «блоки». Каждый блок может быть распределен и сделку независимо. Это позволяет эффективно использовать память, так как вы можете выделить именно столько памяти, сколько вам нужно, не более и не меньше.
Структура блока : каждый блок обычно содержит метаданные о блоке (например, его размер и его свободный или выделенный) и фактические данные, хранящиеся в блоке. Метаданные используются распределителем для управления памятью.
Распределение : Когда вы называете malloc() , выделение ищет бесплатный блок, который достаточно большой, чтобы содержать запрошенную сумму данных. Если он находит один, он отмечает, что это блокируется как выделенное и возвращает указатель на часть данных блока.
Deallocation : Когда вы звоните free() , распределитель отмечает блок как бесплатный, делая его доступным для будущих распределений. Если бесплатный блок находится в конце кучи, выделение также может уменьшить размер кучи, чтобы освободить память.
Фрагментация : со временем, поскольку блоки распределяются и сделка, куча может стать фрагментированной. Это означает, что свободная память разделена на небольшие, негресные блоки. Это может затруднить поиск достаточно большого блока для вызова malloc() , даже если есть достаточно свободной памяти. Чтобы справиться с этим, выделения часто включают в себя логику для дефрагментации кучи, такую как объединение соседних свободных блоков.