рефераты конспекты курсовые дипломные лекции шпоры

Реферат Курсовая Конспект

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

Стандартные процедуры размещения и освобождения динамической памяти - раздел Компьютеры, Оглавление Динамическая Память. 1 Указатель. 1 Ста...

Оглавление

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

Указатель. 1

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

Стандартные функции обработки динамической памяти. 3

Примеры работы с памятью.. 4

Работа с динамическими массивами. 4

Контрольные вопросы: 6

Комбинированный урок №19

Тема:Динамические структуры данных и их организация с помощью указателей

Цель: изучить принципы организации памяти, дать понятие указателю, сформировать знания о применяемых процедурах и функциях.

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

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

Указатель

Формат описания типа «указатель» следующий: TYPE<идентификатор указателя>=^<тип>; Примеры объявления типов «указатель» и переменных типа «указатель».

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

P5 : ^MAS;

P6 : ^ST;

P7 : ^REC;

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

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

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

3) содержит значение предопределенной константы NIL; такой указатель называется пустым, то есть не указывает ни на какую переменную. Указатель со значением NILсодержит 0 в каждом из четырех байтов. Указатели можно сравнивать с другими указателями ( =, <> ), присваивать им адрес или значение другого указателя, передавать как параметр. Указатель нельзя отпечатать или вывести на экран.

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

<идентификатор указателя>^.

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

TYPE SYM=^CHAR;

ZAP=RECORD

FIELD1, FIELD2: REAL;

END;

M=ARRAY[0..9] OF WORD;

VAR CH : SYM;

REC : ^ZAP;

MAS : ^M;

Begin

CH^:='*';{обращение к динамической переменной типа CHAR, запись в эту область символа звездочка}

READLN (REC^.FIELD1);{обращение к полю FIELD1динамической записи, ввод в него данных с клавиатуры}

WRITELN (MAS[5]^);{обращение к элементу MAS[5]динамического массива, вывод на экран значения указанного элемента}

End.

Фактически можно говорить, что CH^, REC^.FIELD1и MAS[5]^исполняют роль имён динамических объектов в программе, адреса которых хранятся в указателях СH, RECи MASсоответственно.Следует отметить, что обращение к переменным типа POINTER(указателям, которые не указывают ни на какой определенный тип и совместимы со всеми другими типами указателей) приводит к ошибке.

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

Динамическая память может быть выделена двумя способами: 1. С помощью стандартной процедуры New (P); где Р- переменная типа… 2. С помощью стандартной процедуры GetMem (P,size); где P- переменная типа «указатель» требуемого типа; size-…

END;

PTR_REC = ^ REC;

VAR P : PTR_REC;

BEGIN

GETMEM(Р,SIZEOF(REC));{Выделение памяти, адрес выделенного участка фиксируется в Р; размер этой памяти в байтах определяет и возвращает стандартная функция SizeOf, примененная к описанному типу данных; однако, зная размеры внутреннего представления используемых полей, можно было бы подсчитать размер памяти «вручную» и записать в виде константы вместо SizeOf(Rec)}

...

{использование памяти}

...

FREEMEM(P, SIZEOF(REC));{освобождение уже ненужной памяти}

...

Динамическая память может быть освобождена четырьмя способами.

1. Автоматически по завершении всей программы.

2. С помощью стандартной процедуры Dispose (P); где P- переменная типа «указатель» (типизированный).

В результате работы процедуры DISPOSE(P)участок памяти, связанный с указателем P, помечается как свободный для возможных дальнейших размещений. При этом физической чистки указателя Pи связанной с ним памяти не происходит, поэтому, даже удалив этот экземпляр записи, можно все же получить значения ее полей, однако использовать это обстоятельство не рекомендуется. Ввиду различия в способах реализации процедуру DISPOSEне следует использовать совместно с процедурами MARKи RELEASE.

3. С помощью стандартной процедуры FreeMem (P, size); где P- переменная типа «указатель», size- целочисленное выражение размера памяти в байтах для освобождения.

Эта процедура помечает память размером, равным значению выражения SIZE, связанную с указателем P, как свободную (см. пример для GETMEM).

4. С помощью стандартных процедур Mark (P); Release (P); где P- переменная типа «указатель»;

MARK- запоминает состояние динамической области в переменной-указателе Р;

RELEASE- освобождает всю динамическую память, которая выделена процедурами NEWили GETMEMпосле запоминания текущего значения указателя Рпроцедурой MARK.

Обращения к MARKи RELEASEнельзя чередовать с обращениями к DISPOSEи FRЕЕМЕMввиду различий в их реализации.

Например:

VAR P:POINTER;

P1, P2, P3:^INTEGER;

BEGIN

NEW(P1); P1^:=10;

MARK(P); {пометка динамической области}

NEW(P2); P2^:=25;

NEW(P3); P3^:=P2^+P1^;

WRITELN (P3^);

RELEASE(P);{память, связанная с P2^ и P3^, освобождена, а P1^может использоваться}

END.

Стандартные функции обработки динамической памяти

MaxAvail; - эта функция возвращает размер в байтах наибольшего свободного в данный момент участка в динамической области. По этому размеру можно… TYPE ZAP=RECORD FIELD1: STRING [20];

END;

VAR P: POINTER;

BEGIN

...

IF MAXAVAIL <SIZEOF(ZAP) THEN

WRITELN ('HE ХВАТАЕТ ПАМЯТИ!')

ELSE

GETMEM(Р, SIZEOF(ZAP));

...

MemAvail; - эта функция возвращает общее число свободных байтов динамической памяти, то есть суммируются размеры всех свободных участков и объем свободной динамической области. Тип возвращаемого значения - longint.

...

WRITELN('Доступно', MEMAVAIL, 'байтов');

WRITELN('Наибольший свободный участок=', MAXAVAIL, 'байтов');

...

Это решение основано на следующем обстоятельстве. Динамическая область размещается в специально выделяемой области, которая носит название «куча» (HEAP). Куча занимает всю или часть свободной памяти, оставшейся после загрузки программы. Размер кучи можно установить с помощью директивы компилятора М: {$М<стек>, <минимум кучи>, <максимум кучи>}, где <стек>- определяет размер сегмента стека в байтах. По умолчанию размер стека 16 384 байт, а максимальный размер стека 65 538 байт. <минимум кучи>- определяет минимально требуемый размер кучи в байтах; по умолчанию минимальный размер 0 байт. <максимум кучи>- определяет максимальное значение памяти в байтах для размещения кучи; по умолчанию оно равно 655 360 байт, что в большинстве случаев выделяет в куче всю доступную память; это значение должно быть не меньше наименьшего размера кучи.

Все значения задаются в десятичной или шестнадцатеричной формах. Например, следующие две директивы эквивалентны:

{$М 16384,0,655360}

{$M $4000, $0, $A000}

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

Управление размещением в динамической памяти осуществляет администратор кучи, являющийся одной из управляющих программ модуля System.

Примеры работы с памятью

Рассмотрим пример размещения и освобождения разнотипных динамических переменных в куче.

TYPE ST1=STRING[7];

ST2=STRING[3];

VAR I,I1,I2,I3,I4:^INTEGER;

R^:REAL;

S1:^ST1;

S2:^ST2;

BEGIN

NEW(I);

I1^:=1;

NEW(I2);

I2^:=2;

NEW(I3);

I3^=3;

NEW(I4);

DISРОSЕ (I2);{освобождается второе размещение} NEW (I);{память нужного размера (в данном случае два байта) выделяется на… I^:=5; (*2*)

END.

 

В следующем примере используется массив указателей.

USES CRT;

VAR R: ARRAY [1..10] OF ^REAL;

I : 1..10;

BEGIN

RANDOMIZE;{инициализация генератора случайных чисел}

FOR I:=1 TO 10 DO

BEGIN

NEW(R[I]);

R[I]^:=RANDOM;{генерация случайных вещ.чисел в диапазоне 0 <= r[i]^ < 1}

WRITELN(R[I]^);{Вывод случайных чисел в экспоненциальной форме}

END;

END.

Работа с динамическими массивами

При работе с массивами практически всегда возникает задача настройки программы на фактическое количество элементов массива. В зависимости от применяемых средств решение этой задачи бывает различным.

Первый вариант -использование констант для задания размерности массива.

PROGRAM FIRST;

CONST N : INTEGER = 10; { либо N = 10; }

VAR A : ARRAY [1..N] OF REAL;

I : INTEGER;

BEGIN

FOR I := 1 TO N DO

BEGIN

WRITELN ('Введите ', I , '-ый элемент массива ');

READLN (A[I])

END; { И далее все циклы работы с массивом используют N}

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

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

PROGRAM SECOND;

VAR A : ARRAY [1..25] OF REAL;

I, NF : INTEGER;

BEGIN

WRITELN ('Введите фактическое число элементов массива <= 25 ');

READLN (NF);

FOR I:= 1 TO NF DO

BEGIN

WRITELN ('Введите ', I, ' -ый элемент массива ');

READLN (A[I])

END;{ И далее все циклы работы с массивом используют NF}

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

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

PROGRAM DYNAM_MEMORY;

TYPE MAS = ARRAY [1..2] OF <требуемый_тип_элемента >;

MS = ^MAS;

VAR A : MS;

I, NF : INTEGER;

BEGIN

WRITELN ('Введите фактическое число элементов массива');

READLN (NF);

GETMEM (A, SIZEOF( <требуемый_тип_элемента>)*NF);

FOR I := 1 TO NF DO

BEGIN

WRITELN('Введите ', I , ' -ый элемент массива ');

READLN(A^[I])

END;{И далее все циклы работы с массивом используют NF}

. . . . .

FREEMEM (A, NF*SIZEOF (<требуемый_тип_элемента>));

END.

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

USES CRT;

TYPE T1=ARRAY[1..1] OF INTEGER;

VAR A:^T1;

N,M,I,J,K,P:INTEGER;

MAX:INTEGER;

BEGIN

CLRSCR;

WRITE('N='); READLN (N);

WRITE('M='); READLN (M);

GETMEM (A,SIZEOF(INTEGER)*N*M);

FOR I:=1 TO N*M DO READ(A^[I]);

MAX:=A^[1]; K:=1; P:=1;

FOR I:=1 TO N DO

FOR J:=1 TO M DO

IF A^[(I-1)*M+J] > MAX THEN

BEGIN

MAX:=A^[(I-1)*M+J];

K:=I; P:=J

END;

WRITE('строка=',K:2,' столбец=',P:2);

FREEMEM(A,2*N*M);

READKEY;

END.

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

местами.

USES CRT;

TYPE VK=^T1;

T1=ARRAY[1..1] OF INTEGER;

MT=^T2;

T2=ARRAY[1..1] OF VK;

VAR A:MT;

M,N,I,J,K,L:INTEGER;

MAX,MIN:INTEGER;

R:POINTER;

BEGIN

CLRSCR;

READLN (N,M);

GETMEM(A,SIZEOF (POINTER)*M); {выделение памяти под указатели столбцов матрицы}

FOR J:=1 TO M DO

GETMEM (A^[J],SIZEOF(INTEGER)*N); {выделение памяти под элементы столбцов}

FOR I:=1 TO N DO

FOR J:=1 TO M DO

READ(A^[J]^[I]);

FOR I:=1 TO N DO

BEGIN

FOR J:=1 TO M DO

WRITE (A^[J]^[I]:4);

WRITELN

END;

MAX:=A^[1]^[1]; K:=1; MIN:=MAX; L:=1;

FOR J:=1 TO M DO

FOR I:=1 TO N DO

IF A^[J]^[I]<MIN THEN

Begin MIN:=A^[J]^[I]; L:=J; end

ELSE

IF A^[J]^[I]>MAX THEN

BEGIN MAX:=A^[J]^[I]; K:=J; END;

{для обмена столбцов достаточно поменять указатели на столбцы}

IF K<>L THEN R:=A^[K]; A^[K]:=A^[L]; A^[L]:=R

FOR I:=1 TO N DO

BEGIN

FOR J:=1 TO M DO

WRITE(A^[J]^[I]:3,' ');

WRITELN

END;

FOR I:=1 TO M DO

FREEMEM (A^[I],N*SIZEOF(INTEGER));

FREEMEM (A,M*SIZEOF(POINTER))

END.

Контрольные вопросы:

  1. Назначение динамической памяти. В чем состоит отличие динамической памяти от статической?
  2. Дайте определение понятию «указатель». Формат описания. Примеры. Какие состояния может принимать указатель?
  3. Как выполняется обращение к выделенной динамической памяти? Примеры.
  4. Процедуры и функции для работы с динамическими данными. Примеры.
  5. Где размещается динамическая область? Как устанавливается размер «кучи»? Единица измерения размера «кучи».
  6. Работа с динамическими массивами. Дать описание всем вариантам.

– Конец работы –

Используемые теги: Стандартные, процедуры, размещения, освобождения, динамической, памяти0.091

Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Стандартные процедуры размещения и освобождения динамической памяти

Что будем делать с полученным материалом:

Если этот материал оказался полезным для Вас, Вы можете сохранить его на свою страничку в социальных сетях:

Еще рефераты, курсовые, дипломные работы на эту тему:

Виды и типы памяти. Индивидуальные способности памяти человека
I По характеру психической активности... двигательная моторная память на движения и их системы... эмоциональная память на чувства...

Динамически размещаемые данные:память для них выделяется по операции new, существуют они пока эта память не будет освобождена
Замечание В языке С были рассмотрены данные простых и сложных типов Перед новой темой можно привести некоторую классификацию данных... по структуре... данные статической структуры которые получают структуру при описании и сохраняют е не нарушая до конца программы...

Память, виды памяти, методы тренировки памяти
При этом память всегда связывалась с процессом обучения т.е. накопления информации, а попытки объяснения памяти всегда совпадали с известными на… Позже - уже в 19 и начале 20 веков - в связи с созданием таких систем, как… Наконец, в связи с развитием исследований в области генетики и молекулярной биологии, раскрытием механизмов хранения…

Стандартные процедуры и функции обработки файлов
Файлы Файловые переменные Ошибка Закладка не определена... Стандартные процедуры и функции обработки файлов... Текстовые файлы...

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

Коды без памяти. Коды Хаффмена. Коды с памятью
Если S = { w1, w2, , wk } - префиксное множество, то можно определить некоторый вектор v(S) = ( L1, L2, , Lk ), состоящий из чисел, являющихся… Для него выполняется неравенство . (1) Это неравенство называется… Для него справедливо следующее утверждение: если S - какое-либо префиксное множество, то v(S) - вектор Крафта.

Динамическое распределение памяти
Если числа в этих адресах стоящие до двоеточия увеличиваютя от первого к последнему на еденичку,то это означает что на каждый блоквыделен один… Задание 8Программа хранит матрицы ввиде двух структур Struct Matr1 int m, n… Задание 12Задание 14Задание 16Программа выполняет считываниематрицы произвольных размеров из файла разделителями…

Методы размещения и трассировки печатных плат на примере модуля памяти
С переходом на микроэлектронные элементы, резким уменьшением размеров и возрастанием быстродействия схем первое место занимают вопросы обеспечения… Значительно усложнились задачи проектирования и оптимального конструирования… Особую роль печатные платы играют в цифровой микроэлектронике.В наиболее развитой форме многослойный печатный монтаж…

Мнестическая сфера: понятие и виды памяти. Развитие памяти в детском возрасте.
Виды памяти Генетическая память сохраняет информацию, которая определяет анатомическое и физиологическое строение организма в процессе развития и… Она существенно больше зависит от внешних условий. Различают несколько видов и… Эта связь может проявиться в следовании за любым движущимся объектом, впервые увиденным животным в первые часы жизни,…

Организация процедуры проведения мероприятий по стимулированию сбыта
Последние изменения в банковской системе, реальная хозяйственная ситуация в России сегодня привели к жизненной необходимости освоения банками… На это ориентирует универсализация банковской деятельности, выход ее за… Чтобы выжить в конкурентной борьбе, банки осваивают новые виды услуг, новые формы бизнеса, выдвигают на первое место…

0.034
Хотите получать на электронную почту самые свежие новости?
Education Insider Sample
Подпишитесь на Нашу рассылку
Наша политика приватности обеспечивает 100% безопасность и анонимность Ваших E-Mail
Реклама
Соответствующий теме материал
  • Похожее
  • По категориям
  • По работам