Система программирования Турбо Паскаль Встроенный ассемблер графика в Турбо Паскале таунхаусы коммунарка

Этот подход способствовал пониманию того, что нет абсолютной информации об объекте, определение информации зависит от составленной модели объекта. За единицу количества информации принимается такое количество информации, которое содержит сообщение, уменьшающее неопределенность знаний в два раза. Такая единица названа бит. Во многих случаях используют группы бит состоящие из 16 разрядов (слово), 32 разрядов (двойное слово), 48 – разрядов (учетверенное) слово.

Администратор кучи

Как уже отмечалось, администратор кучи - это служебная подпрограмма, которая обеспечивает взаимодействие пользовательской программы с кучей. Администратор кучи обрабатывает запросы процедур NEW, GETMEM, DISPOSE, FREEMEM и др. и изменяет значения указателей HEAPPTR и FREELIST. Указатель HEAPPTR содержит адрес нижней границы свободной части кучи, а указатель FREELIST - адрес описателя первого свободного блока. В модуле SYSTEM указатель FREELIST описан как POINTER, однако фактически он указывает на следующую структуру данных:

type

PFreeRec = ATFreeRec; 

TFreeRec = record

Next : pointer;

Size : pointer 

end;

Эта списочная структура предназначена для описания всех свободных блоков памяти, которые расположены ниже границы HEAPPTR. Происхождение блоков связано со случайной последовательностью использования процедур NEW-DISPOSE или GETMEM-FREEMEM («ячеистая» структура кучи). Поле NEXT, в записи TFREEREC содержит адрес описателя следующего по списку свободного блока кучи или адрес, совпадающий с HEAPEND, если этот участок последний в списке. Поле SIZE содержит ненормализованную длину свободного блока или 0, если ниже адреса, содержащегося в HEAPPTR, нет свободных блоков. Ненормализованная длина определяется так: в старшем слове этого поля содержится количество свободных параграфов, а в младшем - количество свободных байт в диапазоне 0... 15. Следующая функция преобразует значение поля SIZE в фактическую длину свободного блока:

Function BlbckSize(Size: pointer): Longint;

{Функция преобразует ненормализованную длинусвободного блока в байты}

type

PtrRec = record

Lo, Hi : word

end; 

var

LengthBlock: Longint; 

begin

BlockSize := Longint(PtrRec(Size).Hi)*16 + PtrRec(Size).Lo 

end;

Сразу после загрузки программы указатели HEAPPTR и FREELIST содержат один и тот же адрес, который совпадает с началом кучи (этот адрес содержится в указателе HEAPORG). При этом в первых 8 байтах кучи хранится запись, соответствующая типу TFREEREC (поле NEXT содержит адрес, совпадающий со значением HEAPEND, a поле SIZE - ноль, что служит дополнительным признаком отсутствия «ячеек» в динамической памяти). При работе с кучей указатели HEAPPTR и FREELIST будут иметьодинаковые значения до тех пор, пока в куче не образуется хотя бы один свободный блок ниже границы, содержащейся в указателе HEAPPTR. Как только это произойдет, указатель FREELIST станет ссылаться на начало этого блока, а в первых 8 байтах освобожденного участка памяти будет размещена запись TFREEREC. Используя FREELIST как начало списка, программа пользователя всегда сможет просмотреть весь список свободных блоков и при необходимости модифицировать его.

Описанный механизм вскрывает один не очень существенный недостаток, связанный с работой администратора кучи, а именно: в любой освободившийся блок администратор должен поместить описатель этого блока, а это означает, что длина блока не может быть меньше 8 байтов. Администратор кучи всегда выделяет память блоками, размер которых кратен размеру записи TFREEREC, т.е. кратен 8 байтам. Даже если программа запросит 1 байт, администратор выделит ей фактически 8 байт. Те же 8 байт будут выделены при запросе 2, 3 ,..., 8 байт; при запросе 9 байт будет выделен блок в 16 байт и т.д. Это обстоятельство следует учитывать, если Вы хотите минимизировать возможные потери динамической памяти. Если запрашиваемый размер не кратен 8 байтам, в куче образуется <дырка> размером от 1 до 7 байт, причем она не может использоваться ни при каком другом запросе динамической памяти вплоть до того момента, когда связанная с ней переменная не будет удалена из кучи.

Если при очередном обращении к функции NEW или GETMEM администратор не может найти в куче нужный свободный блок, он обращается к функции, адрес которой содержит переменная HEAPERROR. Эта функция соответствует следующему процедурному типу:

type

HeapErrorFun = function (Size:word): Integer;

Здесь SIZE - размер той переменной, для которой нет свободной динамической памяти. Стандартная функция, адрес которой при запуске программы содержит переменная HEAPERROR, возвращает 0, что приводит к останову программы по ошибке периода счета с кодом 203 (см. прил. 3). Вы можете переопределить эту функцию и таким образом блокировать останов программы. Для этого необходимо написать собственную функцию и поместить ее адрес в указатель HEAPERROR. Например:

Function HeapFunc(Size: Word): Integer; far; 

begin

HeapFunc := 1 end; 

begin {Основная программа}

HeapError := @HeapFunc;

.......

end.

Отметим, что функция типа HEAPERRORFUN вызывается только в том случае, когда обращение с требованием выделения динамической памяти было неуспешным. Она может возвращать одно из трех значений:

0 - прекратить работу программы;

1 - присвоить соответствующему указателю значение NIL и продолжить работу программы;

2 - повторить выделение памяти; разумеется, в этом случае внутри функции типа HEAPERRORFUN необходимо освободить память нужного размера.

 

В 1833 - 1871 гг. английский ученый Чарлз Бэббидж разработал проект «аналитической машины», которая имела все основные узлы современной ЭВМ: «склад» (память), «мельницу» (арифметическое устройство) и «управление» (уст-ройство управления). Здесь впервые был реализован принцип разделения информации на команды и данные.
Способ хранения данных в Turbo Vision