Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ТП.doc
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
562.18 Кб
Скачать
  1. Динамическая память и указатели. Типы указателей. Описание указателей.

Если размещение переменных происходит во время компиляции, оно называется статическим, при этом должно быть заранее известно количество размещаемых переменных и их тип.

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

Любая ячейка собственной памяти – байт характеризуется собственным адресом. Адреса ячеек могут храниться в переменных специального типа – указателях. Адрес занимает четыре байта.

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

Имеется два типа указателей: указатель на объект некоторого типа и указатель без типа, т.е. типизированные и нетипизированные.

Описание указателей

Типизированный указатель хранит адрес переменной определенного типа.

Var

<имя указателя>:^<тип>;

Нетипизированный указатель не связанный с каким-либо конкретным типом данных

Var

<имя указателя>: Pointer;

Оба указателя могут предварительно объявляться как тип, а затем по типу описываться переменные.

Var

p: ^ real; //переменная, в которой будет записан адрес вещественного числа

Выполняя это описание компилятор:

- для указателя p статически выделит 4 байта памяти, в которых будет храниться адрес байта, начиная с которого в динамической памяти (куче или heap) может размещаться вещественное число длинной 8 байт;

- указателю будет присвоено значение nil, т.е. p не содержит после описания никакой адрес.

Var

p: Pointer;

Выполняя это описание компилятор:

- для указателя p статически выделит 4 байта памяти, в которых будет храниться адрес байта начала какого-либо переменного или программного кода;

- указателю будет присвоено значение nil.

  1. Операции над указателями. Выделение динамической памяти для типизированных и нетипизированных указателей. Проблема утечки памяти.

Для указателей определены операции:

- присваивания p1 := p2;

    • Любому указателю можно присвоить стандартную константу nil, которая означает, что указатель не ссылается на какую-либо конкретную ячейку памяти: p1 := nil;

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

    • Указатели стандартного типа pointer совместимы с указателями любого типа.

- проверки на равенство и неравенство if p1 = p2 then …;

- разыменование указателя p^; применяется для обращения к значению переменной, адрес которой хранится в указателе:

var

p1: ^word;

L:word;

// предварительно в p1 должен быть записан адрес отличный от nil

p1^ := 2; // по адресу указанному в p1 отослать значение 2,

p1^ := p1^ +1;

L:=2* p1^ ;

inc(p1^);

writeln(p1^);

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

- взятие адреса переменной p:= @ a. Получение адреса переменной.

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

Процедура Dispose(p1), наоборот освобождает память выделенную под переменную, указатель остается ему присваивается значение nill возможно его дальнейшее использование.

Например,

Var

P:^integer;

Begin

New(P);

Read(P^);

inc(P); //заметим, что P увеличится на размер типа integer, т.е. 4 байта

Dispose(P);

End.

Для нетипизированных указателей память под динамически размещаемую переменную следует выделять процедурой GetMem, высвобождать FreeMem

Procedure GetMem(var P:pointer; Size: Integer); - резервирует за указателем фрагмент памяти размером Size байтов.

Procedure FreeMem(var P:pointer [; Size: Integer]); - возвращает в динамическую память фрагмент, который был зарезервированным указателем P.

Function SizeOf(x):Integer; - возвращает количество байтов, занимаемой переменной или типом х.

Var

p: pointer;

begin

GetMem(p,28);

…..

FreeMem(p);

End.

Для контроля утечки памяти полезны функции:

  • Функция Maxavail : longint возвращает длину в байтах самого длинного свободного участка динамической памяти.

  • Функция Memavail : longint возвращает полный объем свободной динамической памяти в байтах.

  • также SizeOf(x):

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]