Программирование в среде Турбо Паскаль (Поляков, Круглов) - страница 135

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

| > { Заполнение видеопамяти}