Помощничек
Главная | Обратная связь


Археология
Архитектура
Астрономия
Аудит
Биология
Ботаника
Бухгалтерский учёт
Войное дело
Генетика
География
Геология
Дизайн
Искусство
История
Кино
Кулинария
Культура
Литература
Математика
Медицина
Металлургия
Мифология
Музыка
Психология
Религия
Спорт
Строительство
Техника
Транспорт
Туризм
Усадьба
Физика
Фотография
Химия
Экология
Электричество
Электроника
Энергетика

Стандартные процедуры размещения и освобождения



Динамическая память.

 

Общая характеристика статической памяти:

· момент распределения памяти; освобождение памяти;

· за именем – адрес;

· механизм распределения памяти, роль типа данных в распределении памяти.

В предшествующих разделах использовались переменные, память под которые выделялась статически, то есть на стадии компиляции. Эти области памяти (для переменных из раздела VAR данного блока) существуют до конца работы блока, даже если эти переменные уже не нужны. При этом память нередко используется неэффективно.

Исправить положение можно, применив специальный механизм распределения памяти.

 

 

Турбо Паскаль предоставляет возможность выделять и освобождать память в процессе выполнения программы, динамически.

Место динамической памяти – куча (heap).

Достоинства динамической памяти:

- экономичность и эффективность ее использования;

- возможность динамического изменения числа элементов в связанных структурах, например, списках (в статической памяти число элементов фиксировано для каждой компиляции);

- статические переменные существуют только в течение жизни блока, в котором они объявлены, а динамические - и после выхода из блока до окончания программы, а на практике – столько, сколько нужно по алгоритму;

- переменная, размещаемая динамически, не объявляется в разделе VAR и не имеет имени в программе («невидимка»), но нужен тип. Компилятор не планирует выделение места в памяти под такие переменные.

Недостатки динамической памяти:

- усложняются процессы выделения и освобождения динамической памяти по сравнению со статической;

- усложняются алгоритмы обработки данных, представленных динамическими структурами.

Указатель.

 

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

Переменная типа «указатель» содержит адрес размещения участка динамической памяти, с которой связан этот указатель.

Компилятор отводит под переменную типа «указатель» четыре байта статической памяти.

Как правило, указатель связан с определенным типом данных и является типизированным. Однако он может быть и не типизированным, то есть совместимым с указателями любого типа данных. В этом случае указатель называется свободным (несвязанным). При этом может возникнуть вопрос – а с какими, собственно, данными мы имеем дело (их тип и, соответственно, допустимые операции над ними).


Формат описания типа «указатель» :

TYPE

Идентификатор_указателя = ^тип ;

или Ид_ук = ^тип ;

 

Что означает эта запись: в поле ид_ук может быть записан адрес поля, содержащего значение указанного типа.Это значит также, что, адрес, хранящийся в переменной адресного типа, связан с типом хранимого значения (контроль данных)

 

Примеры объявления типов «указатель» и переменных типа «указатель».

Type

{правильные объявления типов}

p1=^word;{ p1 - идентификатор типа «указатель» на

данные типа word.}

p2=^char; { p2 - идентификатор типа «указатель» на

данные типа char}

p4=array[1..10] of ^real; {p4 - идентификатор типа

«указатель» на массив

указателей, ссылающихся

на данные типа real}

{неправильные объявления типов}

p5=^array[1..10] of real;

p6=^string[25];

p7=^record

field1 : string [15];

field2 : real;

end;

 

В формате объявления типа «указатель» должен быть указан идентификатор типа, поэтому стандартные идентификаторы (integer, real и т.д.) можно указывать непосредственно в описаниях типа «указатель». Ошибки в описаниях типов p5, p6 и p7 будут отмечены компилятором из-за того, что, в таких случаях надо прежде описать идентификатор типа, а затем использовать его в других описаниях.


Следующие описания будут правильными:

Type

mas = array[1..10] of real;

st = string[25];

rec = record

field1 : string [15];

field2 : real;

end;

Var

{ типы могли быть описаны и в type}

p5 : ^mas;

p6 : ^st;

p7 : ^rec;

...

 

Сначала объявлены типы, а затем – адресные типы для хранения указателей на них.

 

Указатель может находиться в одном из трех состояний, а именно:

1) не инициализирован;

2) содержит адрес размещения;

3) содержит значение предопределенной константы nil; такой указатель называется пустым, то есть не указывает ни на какую переменную.

 

Указатели можно

ü сравнивать с другими указателями ( =, <> ),

ü присваивать им адрес или значение другого указателя,

ü передавать как параметр.

 

Указатель нельзя

ü отпечатать;

ü вывести на экран.

 

Обращение к выделенной динамической памяти кодируется следующим образом:

 

Идентификатор_указателя^

 

Рассмотрим пример обращения к переменным, размещенным в динамической памяти:

Type

sym=^char;

zap=record

field1, field2: real;

end;

m=array[0..9] of word;

Var

ch : sym;

rec : ^zap;

mas : ^m;

...

ch^:='*'; {обращение к динамической переменной типа char,

запись в эту область символа звездочка}

...

Readln (rec^.field1); {обращение к полю field1 динамической

записи, ввод в него данных с клавиатуры }

...

Writeln ( mas[5]^); {обращение к элементу mas[5]

динамического массива,

вывод на экран значения указанного элемента}

...

Фактически можно говорить, что ch^, rec^.field1 иmas[5]^ исполняют роль имён динамических объектов в программе, адреса которых хранятся в указателях сh, rec и mas соответственно.

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

Например.

Var

p:pointer;

...

p^:=1; {ошибка!}

 

 


 

Стандартные процедуры размещения и освобождения

Динамической памяти.

 

При выполнении программы наступает момент, когда необходимо использовать динамическую память, т.е. выделить её в нужных видах, разместить там какие-то данные, поработать с ними, а после того, как в данных отпадет необходимость - освободить выделенную память.

Динамическая память может быть выделена следующими способами:

1. С помощью стандартной процедуры New:

New (P);

где р - переменная типа «типизированный указатель».

 

Эта процедура: 1) создает новую динамическую переменную, то есть выделяет под нее участок памяти, и 2) в P записывает адрес выделенного участка памяти, то есть устанавливает на него указатель P  

 

 

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

 

Доступ к значению созданной переменной можно получить с помощью обращения вида P^.

 




©2015 studenchik.ru Все права принадлежат авторам размещенных материалов.