Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конструирование программ.doc
Скачиваний:
12
Добавлен:
05.05.2019
Размер:
12.37 Mб
Скачать

3.5.2 Процедуры выделения и освобождения памяти

3.5.2.1 New и Dispose

В этих процедурах размер запрашиваемой и освобождаемой памяти явно не указывается в процедуре и определяется типом данных. Поэтому описание указателя должно быть только такого вида: ^<имя типа данных>.

New(P) – выделить память, размер которой определяется типом данных указателя P. После успешного завершения операции New значением переменной P становится начальный адрес выделенный области памяти.

Выделяемая процедурой New память не инициализируется каким-либо значением.

Dispose(P) – освободить память, начальный адрес, который определяется значением указателя P. Размер освобождаемой памяти определяется типом данных указателя P.

3.5.2.2 GetMem и FreeMem

В этих процедурах размер запрашиваемой и освобождаемой памяти явно указывается в процедуре.

Для определения необходимого размера выделяемой памяти для информации различного типа рекомендуется использовать функцию Sizeof().

GetMem(P, Size)выделить память размером Size (единовременно не более 65528 байт) и поместить значение начального адреса выделенной области памяти в указатель P.

FreeMem(P, Size)освободить выделенную память размером Size, начальный адрес которой определяется значением указателя P.

3.5.3 Односвязный список

Списком называется упорядоченная динамическая структура данных, каждый элемент которой содержит данные и ссылку (указатель), связывающую его со следующим элементом (рисунок 3.6).

Рисунок 3.6 – Структура списка

Структура элемента списка может быть объявлена в программе, например, следующим образом:

type

ptrList = ^TList;{ тип указателя связан со структурой элемента списка }

TList = record { структура элемента списка: }

inf : <тип данных>; { информация (данные) }

next: ptrList; { указатель на элемент списка }

end;

Рассмотрим типовые схемы создания, просмотра и удаления списка на примере односвязного списка, структура которого приведена выше.

Создание списка

Схема создания списка (шаг 1 и шаг 2) приведена на рисунке 3.7.

var

p1, p2, pList: ptrList; { p1 – указатель на новый элемент списка }

{ p2 – вспомогательный указатель, в начале = NIL}

{ pList – указатель на начало списка }

begin

p2 := NIL; { список пуст }

<Цикл добавления элементов в список>

begin

New(p1); { выделяем память для элемента списка }

p1^.inf := <данные>; { формируем данные элемента списка }

p1^.next := p2; { "связываем" элементы списка }

p2 := p1; { сохраняем адрес элемента списка в p2 }

end;

pList:= p2; { Список создан. pList – адрес начала списка }

end.

Просмотр списка

var

p1, pList: ptrList; { pListуказатель на начало списка }

begin

p1 := pList;

while p1<> NIL do begin

<.использование данных элемента списка (p1^.inf) >;

p1 := p1^.next; { перемещаем указатель p1 на следующий элемент }

end;

end.

Рисунок 3.7 – Схема создания списка из двух элементов

Удаление списка

var

p1, p2, pList: ptrList; { pListуказатель на начало списка }

begin

p1 := pList;

while p1<> NIL do begin

p2:=p1; { сохраняем адрес элемента списка в p2 }

p1 := p1^.next; { перемещаем указатель p1 на следующий элемент }

dispose(p2); { удаляем элемент списка, адрес которого p2 }

end;

pList:=NIL; { список пуст }

end.

Советы профессионала

  • Проверяйте указатели перед применением

  • Проверяйте переменную, на которую указывает указатель, перед ее использованием

  • Нарисуйте картинку, которая поможет понять логику использования указателя

  • Удаляйте указатели в списках в правильном порядке. Удаление указателя на первый элемент может сделать невозможным доступ к другим элементам списка!

  • Устанавливайте указатель в Nil при удалении указателя

  • Изолируйте работу с указателями в подпрограммах

  • Ошибка в указателе – чаще всего, это следствие того, что он указывает не туда, куда должен.