
- •1.2. Понятие алгоритма. Словесное задание алгоритмов
- •III. Тело алгоритма.
- •1.3. Типы алгоритмов. Операция присваивания
- •1.4. Графическое задание алгоритмов. Блок-схемы. Исполнение алгоритмов
- •2. Структурное программирование. Общие сведения по алгоритмическому языку паскаль и его среде разработки
- •2.1. Предпосылки появления и основные принципы структурного программирования
- •2.2. Язык программирования Турбо Паскаль. Единая интегрированная среда разработчика Turbo Pascal 7.0 (tp 7.0), структура ее диалогового окна и основные команды
- •2.3. Компилятор языка Паскаль Free Pascal ( fpc). Среда разработки Free Pascal ide
- •3. Основные элементы языка Паскаль. Алфавит. Идентификаторы. Типы данных. Выражения. Операции. Отношения. Математические функции в языке Паскаль
- •3.1. Синтаксис и семантика в описании алгоритмического языка. Алфавит языка Турбо-Паскаль
- •3.2. Элементарные конструкции языка Паскаль
- •3.3. Общая структура типов данных. Простые типы в языке Паскаль
- •3.4. Выражения, математические, логические операции, отношения, математические функции в языке Паскаль
- •3.5. Память пк, сегментная адресация, динамическая память
- •3.6. Указатели и динамические переменные
- •3.6.1. Виды указателей и их описание
- •3.6.2. Действия с указателями
- •3.6.3. Выделение и освобождение динамической памяти
- •4. Составной Оператор. Понятия функции и процедуры. Пользовательский интерфейс, Структура программ на языке Паскаль
- •4.1. Составной оператор, понятия функции и процедуры в языке Паскаль
- •4.2. Понятие интерфейса пользователя. Средства создания текстового пользовательского интерфейса в Паскале
- •4.3. Реализация базовых функций интерфейса по вводу и выводу данных в Паскале
- •4.4. Использование библиотеки crt для создания текстового пользовательского интерфейса
- •Рассмотрим выполнение отдельных функций по работе с текстовым экраном при помощи подпрограмм из библиотеки crt.
- •Процедуры работы со звуком.
- •Процедура ожидания.
3.6.3. Выделение и освобождение динамической памяти
Динамические переменные создаются в динамической памяти (хипе) во время выполнения программы с помощью подпрограмм new (для типизированных указателей) или getmem (выделение нетипизированной памяти). Динамические переменные не имеют собственных имен, к ним обращаются через указатели. Выделение памяти и формирование указателей производится следующим образом.
1. Процедура new(var p:тип_указателя) выделяет в хипе участок размера, достаточного для размещения переменной того типа, на который ссылается указатель p, и адрес начала этого участка заносит в этот указатель.
2. Функция new(тип_указателя):pointer выделяет в хипе участок размера, достаточного для размещения переменной базового типа для заданного типа указателя, и возвращает адрес начала этого участка.
3. Процедура getmem(var p: pointer; size: word) выделяет в хипе участок размером в size байт и присваивает адрес его начала указателю p.
Если выделить требуемый объем памяти не удалось, программа аварийно завершается. Указатели могут быть любого типа.
Освобождение динамической памяти осуществляют с использованием процедур Dispose (при выделении памяти с помощью new) и Freemem - в противном случае.
4. Процедура Dispose(var p : pointer) освобождает участок памяти, выделенный для размещения типизированной динамической переменной процедурой или функцией new, и значение указателя p становится неопределенным.
5. Процедура Freemem (var p : pointer; size : word) освобождает участок нетипизированной памяти размером size, начиная с адреса, находящегося в p. Значение указателя после завершения действий становится неопределенным.
Если требуется освободить память из-под нескольких переменных одновременно, можно применять процедуры Mark и Release.
6. Процедура Mark(var p : pointer) записывает в указатель p адрес начала участка свободной динамической памяти на момент ее вызова.
7. Процедура Release(var p : pointer) освобождает участок динамической памяти, начиная с адреса, записанного в указатель p процедурой Mark.
Освобождение динамической памяти должно дополняться очисткой указателя на нее путем присваивания ему пустого значения nil .
При завершении программы используемая ею динамическая память освобождается автоматически.
Пример 7 программы, в которой выполняется работа с динамическими переменными.
type pint = ^integer; { описание типа указателя pint на величины типа integer }
var p1, p2 : pint; { описание указателей p1,p2 на величины типа integer }
p3 : ^char; { описание указателя p3 на величины типа byte }
i:integer; ch:char; { описание переменной i типа integer и ch типа char }
begin
new(p1); { выделение в хипе памяти для переменной типа integer,ссылка на нее - в указателе p1}
p2:=new(pint);{выделение памяти переменной integer, присвоение ссылки на нее указателю p2}
new(p3); { выделение в хипе памяти для переменной типа char,ссылка на нее - в указателе p3}
p1^:=2; { присваивание динамической переменной по указателю p1 значения, равного 2 }
i:=p1^+1; p2^:=(i+2)*5+2; { присваивание значения динамической переменной по указателю p2 }
ch:='A'; p3^:=ch; { присваивание значения динамической переменной по указателю p3 }
writeln('p1^=',p1^,' p2^=',p2^,' p3^=',p3^);{вывод динам. переменных по указат. p1-р3}
dispose(p1); p1:= nil; {освобождение памяти для динамической переменной по p1,очистка p1}
dispose(p2); p2:= nil; {аналогичные действия для p2,p3}
dispose(p3); p3:= nil;
end.
Использование указателей на подпрограммы рассмотрено в Главе 7.
Вопросы для проверки знаний.
1. В чем смысл введения указателей ?
2. Какие указатели называют стандартными, а какие типизированными ?
3. Каким образом указатели в Free Pascal могут задавать массив бесконечной длины ?
4. В чем заключается операция получения адреса переменной ?
5. В чем заключается операция разыменования ?
6. Где создаются динамические переменные ?
7. В чем отличие применения подпрограмм new и getmem для выделения динамической памяти ?
8. В чем отличие применения подпрограмм Dispose и Freemem для освобождения динамической памяти ?
9. Каким действием должно дополняться освобождение динамической памяти ?