Freemem (p3, 300)

Рис. 44. Распределение области памяти кучи после выполнения запросов на выделение памяти

Рис. 43. Распределение области памяти кучи после загрузки программы

Рис. 42. Распределение области памяти кучи

 

Каждый свободный блок описывается дескриптором, имеющим следующую структуру:

 

Type PFreeRec = ^ TFreeRec;

TFreeRec = record

next: pointer;

size: pointer

end;

Var FreeList: PFreeRec;

 

Т.о., указатель FreeList указывает на дескриптор первого свободного блока в куче. Данная списочная структура предназначена для описания всех свободных блоков памяти, которые расположены ниже границы HeapPtr. Происхождение блоков связано со случайной последовательностью запросов на выделение / освобождение памяти в процессе выполнения программы. Поле next в записи TFreeRec указывает на дескриптор следующего по списку свободного блока кучи или содержит адрес, совпадающий с HeapEnd, если этот участок последний в списке. Поле size содержит размер свободного блока (в байтах), представленный в ненормализованном виде, или 0, если ниже адреса, содержащегося в HeapPtr, нет свободных блоков. Ненормализованная длина определяется так: в старшем слове поля size содержится число свободных параграфов, т.е. участков размером 16 байт, а в младшем слове - число байт в диапазоне 0..15.

Сразу после загрузки программы указатели HeapPtr и FreeList содержат один и тот же адрес, который совпадает с началом кучи и находится в HeapOrg. При этом в первых восьми байтах кучи хранится запись, соответствующая типу TFreeRec (поле next содержит адрес, совпадающий со значением HeapEnd, а поле size – нулевое значение) (рис. 43).

 
 

 


 

После выполнения серии запросов на выделение памяти область кучи будет распределена следующим образом (рис. 44):


 

Getmem (p1, 100); Getmem (p2,200);

Getmem (p3, 300);

Getmem (p4, 400);

 

 

 

p1, p2, p3, p4 - указатели из программы пользователя.

 

 

При работе с кучей указатели HeapPtr и FreeList будут иметь одинаковые значения до тех пор, пока в куче не образуется хотя бы один свободный блок ниже границы, содержащейся в указателе HeapPtr. Как только это произойдет, указатель FreeList станет ссылаться на начало этого блока, а в первых восьми байтах освобожденного участка памяти будет размещен дескриптор, т.е. запись TFreeRec (рис. 45, 46).