|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#16
|
|||
|
|||
Да не, задание, на самом деле, достаточно простое.
Код:
type PMemBlock = ^TMemBlock; TMemBlock = record StartAddr : Integer; BlockSize : Integer; End; var PhisicalMem : Array [0..1023] Of Byte; MemBlocks : TList; // лень с массивами возиться // Выделение памяти function MM_GetMem(ASize : Integer) : Integer; var I : Integer; B : PMemBlock; begin Result := -1; If ASize < Length(PhisicalMem) Then Begin // если нету еще выделенных блоков If MemBlocks.Count = 0 Then Begin New(B); B.StartAddr := Low(PhisicalMem); B.BlockSize := ASize; MemBlocks,Add(B); Result := B.StartAddr; Exit; End; // Блоки есть, проверяем самое начало If MemBlocks[0].StartAddr > ASize Then Begin New(B); B.StartAddr := Low(PhisicalMem); B.BlockSize := ASize; MemBlocks,Add(B); Result := B.StartAddr; Exit; End; // Блоки есть, пробуем найти свободное место между блоками For I := 0 To MemBlocks.Count-2 Do If (MemBlocks[I+1].StartAddr - (MemBlocks[i].StartAddr + MemBlocks[i].BlockSize)) >= ASize Then Begin New(B); B.StartAddr := MemBlocks[i].StartAddr + MemBlocks[i].BlockSize + 1; B.BlockSize := ASize; MemBlocks.Insert(B,I+1); Result := B.StartAddr; Exit; End; // Пока не нашли. Смотрим в конец памяти If Result = -1 Then Begin If High() - (MemBlocks[MemBlocks.Count-1].StartAddr + MemBlocks[MemBlocks.Count-1].BlockSize) >= ASize Then Begin New(B); B.StartAddr := MemBlocks[i].StartAddr + MemBlocks[i].BlockSize + 1; B.BlockSize := ASize; MemBlocks.Insert(B,I+1); Result := B.StartAddr; End; End; end; end; // Освобождение памяти function MM_FreeMem(AAddr : Integer) : Result; var I : Integer; B : PMemBlock; begin Result := -1; For I := 0 To MemBlocks.Count-1 Do If MemBlocks[i].startAddr = AAddr Then Begin B := MemBlocks[i]; MemBlocks.Delete(I); Dispose(B); Result := I; Exit; End; end; Ну и т.д. Последний раз редактировалось lmikle, 11.11.2016 в 08:16. |
#17
|
|||
|
|||
А что из себя строка
Код:
MemBlocks : TList; |
#18
|
|||
|
|||
Все, я прогуглил) "Класс TList очень полезный универсальный контейнер списков "
|
#19
|
||||
|
||||
Все бы хорошо, но TList использует алгоритм, который собственно тут и изобретают
Пишу программы за еду. __________________ |
#20
|
|||
|
|||
Num, не совсем. TList - это просто список каких-то данных.
Тут изобретают алгоритм управления ФИЗИЧЕСКОЙ памятью. По поводу содания. Где-то в программе (например, при старте) надо создать это список, а потом, в конце работы, его уничтожить. |
#21
|
||||
|
||||
Да, TList это список, который для хранения элементов использует массив указателей, память для которого выделяется функцией ReallocMem, аналог которой в этой теме изобретают
protected procedure TList.SetCapacity Пишу программы за еду. __________________ |
#22
|
|||
|
|||
Только то,что привёл lmikle, использует дополнительную память.
Судя по заданию, все объекты типа MemBlock должны располагаться внутри массива PhisicalMem. |
#23
|
|||
|
|||
Ок, что мешает, в принципе, выделить блок из PhisicalMem и в TList добавить указатель на него?
Или просто зарезервировать в начале какой-то кусок под таблицу, а для простоты сделать блоки фиксированного размера (как оно, соб-сно, и имплементировано в реальном мире - размер страницы 4К ни о чем не напоминает??? Или выравнивание на 16 байт??? Было бы желание, просто с 1К памяти особо не разбежишься) Например, делаем блоки по 16 байт. Тогда макс мы можем выделить 1024/16 = 64 блока. Что бы адресовать 64 блока нам надо зарезервировать первые 64 байта для описателей (это если мы хотим все сделать по простому, т.е. не связваться с битовой арифметикой). Т.е. из 64 блоков 4 резервируем для служебных нужд. Тогда можно обойтись и без списка, но принципиально это ничего не поменяет. |