![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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 резервируем для служебных нужд. Тогда можно обойтись и без списка, но принципиально это ничего не поменяет. |