Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
45
Добавлен:
23.03.2015
Размер:
884 Кб
Скачать

144 Глава 7

intqueue = data type is q_new, q.isempty, q_append,

q-remfirst

Описание

Типы данных intqueue используются для хранения значений типа целого числа. Элементы могут извлекаться из очереди или удаляться из нее только методом обратного магазинного типа («первым пришел — первым обслужен») Операции function q_new: intqueue

effects Возвращает новую очередь без элементов в ней. function qJsempty (q: intqueue): boolean

effects Возвращает значение true, если в очереди q нет элементов, в про­тивном случае возвращает значение false. procedure q .append (q; intqueue; e: integer) modifies q

effects Добавляет элемент e в конец очереди q. function q_rernfirst (q: intqueue): integer requires чтобы очередь q была не пустой, modifies q effects Возвращает элемент из начала очереди q и удаляет этот элемент из

очереди q. end intqueue

Рис. 7.1. Спецификация очереди целых чисел.

кой, чтобы гарантировать то, что абстрактные объекты могут быть возвращены при помощи функций. Если бы, например, пред­ставление было некоторой записью, содержащей в качестве своей компоненты некоторый указатель, то его нельзя было бы вернуть при помощи функции. И наконец, использование указателя га-раш нрует эффективность при передаче абстрактных объектов по значению.

По соглашению объявление типа представления всегда будет в такой форме:

type type: iai-ne == ^typename.rep;

где typename.rep является некоторым типом, который описывает «реальное» представление. Например, для типа intqueue мы ис­пользуем такой тип представления:

type

intqueue = ^intqueue.rep; intqueue. rep = '[•intqLleue.elem; intqueue_elem == record val: integer; next: intqueue. rep; end;

Следуя нашим соглашениям, просто объявить переменные не­которого абстрактного типа, например,

var q: intqueue;

Смысл этого объявления состоит в том, что в стеке отводится пространство для некоторой неинициализированной переменной q.

Использование языка Паскаль

Размер этого пространства такой, чтобы поместился некоторый указатель, как в языке CLLJ.

Когда очередь q объявлена, выделяется только указатель, и, следовательно, когда организуется выход из процедуры, в ко­торой объявлена очередь q, освобождается только этот указатель. Место для элементов очереди q выделяется в операциях типа intqueue при помощи явных обращений к примитиву new языка Паскаль. Поскольку в языке Паскаль сборка мусора автоматически не осуществляется, пространство, занятое этими элементами, должно быть явно освобождено той программой, в которой ис­пользуется данная очередь. Для этой цели в языке Паскаль имеется примитив dispose. Указатель задается как аргумент для этого примитива, он следует этому указателю и освобождает то пространство, на которое указывает данный указатель. Размер освобождаемого пространства зависит от типа указателя. Прими­тив dispose (q) будет освобождать пространство, занятое одним указателем типа intqueue.rep. Это означает, что вся память, занимаемая элементами, будет оставаться занятой, и это может привести к особенно неприятной ошибке в программе, называе­мой «утечкой памяти». Утечка памяти происходит тогда, когда не была освобождена память, которая должна быть освобождена. Единственным симптомом этой ошибки является то, что через некоторое время неупорядоченный массив постепенно исчерпы­вается. К тому времени, когда в программе кончится такое про­странство, может выполниться очень много команд от того места, где произошла сама утечка.

Чтобы гарантировать правильное освобождение пространсчЕа, для каждого типа дожна существовать некоторая дополнительная операция, которая называется destroy. Операция destroy исполь­зует один аргумент — некоторый объект данного типа, и она освобождает все пространство в неупорядоченном массиве, свя­занное с этим объектом. Значение данного объекта при возврате из операции destroy не определено. Приведем спецификацию процедуры q.destroy.

procedure q. destroy (q: intqueue) modilSes q

efiects В неупорядоченном массиве освобождается вся память, занимаемая очередью q.

По соглашению пользователи никогда не освобождают абст­рактные объекты непосредственно. Вмесго этого они обращаются к операции destroy для типа данного объекта. При этом согла­шении размер освобождаемого пространства находится под кон­тролем. При этом, однако, не гарантируется, что к освобожден­ному объекту не будет больше ссылок. Если такая ссылка сущест­вует, то после освобождения данного объекта она становится «повисающей ссылкой». Если делается попытка получить доступ

Соседние файлы в папке POSIBNIK