HeapError := @UserHeapFunc;
Мало смысла в том, чтобы писать свои функции HeapFunc, возвращающие значение 0. Программа и так оборвется при нехватке памяти в куче. Зато очень удобно обрабатывать ошибки распределения памяти, если установить возвращаемое значение равным 1:
{$F+}
FUNCTION HeapFunc(Size : Word) : Integer;
BEGIN
HeapFunc := 1
END;
{$F-}
и подставить эту функцию через переменную HeapError. Теперь можно анализировать последствия работы любой процедуры размещения динамических переменных:
...
New(P);
if P = nil then обработка ситуации нехватки памяти;
{иначе нормальная работа с P^}
...
Если пойти еще дальше, то можно написать функцию HeapFunc такой структуры:
- 211 -
($F+}
FUNCTION HeapFunc( Size : Word ) : Integer;
BEGIN
{ ОСВОБОЖДЕНИЕ КАКИМ-ЛИБО СПОСОБОМ Size БАЙТ В КУЧЕ }
HeapFunc := 2 {и повтор неудачного распределения }
END;
{$F-}
Начальное значение переменной HeapError при старте программы равно nil. Его же надо восстанавливать, если отпала необходимость в обработке ошибок кучи.
11.6. Ссылки, работающие не с кучей
Традиционно понятие «ссылка» всегда увязывается с динамическими переменными, кучей и т.п. У Турбо Паскаля тоже есть традиции. Одна из них — расширение общепринятых стандартов. В частности, ничто, кроме традиционных учебников стандартного Паскаля, не обязывает связывать ссылки или указатели именно с кучей. Ссылки могут указывать на что угодно: даже на выполнимый код программы (крайний и бесполезный случай). Обычно в разных трюках ссылки связываются со статическими данными или с системными областями памяти ПЭВМ (областью данных БСВВ, видеопамятью и др.).
Кроме способа связывания, такие ссылки ничем не отличаются от рассмотренных ранее (рис. 11.8).
| PROGRAM NoHeap;
| { ПРИМЕР ССЫЛОК БЕЗ ИСПОЛЬЗОВАНИЯ КУЧИ }
| TYPE { базовые типы: }
| >VideoArray=Array[1..4000] of RECORD {структура экрана }
| >Symbol : Char;
| >Attrib : Byte
| END;
| >Vector=Array[1..100] of Real; { одномерный массив }
| >Matrix=Array[1..10,1..10] of Real;{ матрица 10 на 10 }
| VAR
| >VideoPtr : ^VideoArray; { ссылка на структуру экрана }
| >Vec : Vector; { ссылка на одномерный массив }
| >MatPtr : ^Matrix; { ссылка на массив — матрицу }
| >P : Pointer; { просто указатель }
| >i : Word; { счетчик для циклов }
Рис. 11.8
- 212 -
| BEGIN
| >VideoPtr := Ptr( $B800, 0 );
{Переменная VideoPtr теперь содержит адрес начала видеопамяти в цветных и черно-белых режимах. Для режима mono надо подставить в присваивании Ptr{$B000,0). После этого можно непосредственно обращаться к видеопамяти. }
| >for i:=1 to 4000 do begin
| > { Заполнение видеопамяти}