Студопедия

КАТЕГОРИИ:

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


Федоров А.М.




Динамическое распределение памяти. Использование динамической памяти в программах: типичные ошибочные ситуации и способы их предотвращения.

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

Вследствие этих причин используют так называемое динамическое распределение памяти (ДРП), позволяющее выделять (и освобождать) необходимые участки памяти в процессе выполнения программы. Естественно, что процессы выделения и освобождения жестко связаны с системой адресации и структурой памяти операционной системы и ЦВМ. Для того чтобы не утруждать программиста высокого уровня подробностями выделения и управления памятью, широко используют указатели. Для работы с указателями существует несколько процедур и функций: Addr – адрес указанного объекта; CSeg – текущее значение регистра CS; DSeg - текущее значение регистра DS; Ofs – смещение объекта в памяти; Seg – сегмент объекта; SPtr – текущее значение регистра SP; SSeg - текущее значение регистра SS; MaxAvail – размер в байтах наибольшего непрерывного свободного блока в куче; MemlAvail – кол-во свободных блоков в куче. Каждый указатель содержит адрес сегмента и размер смещения. Это позволяет «обманывать» компилятор путем приведения типов.

При использовании динамической памяти всегда следует понимать, что вы хотите взять - сам указатель или переменную, на которую он указывает. И поступать соответственно. [Все динамические переменные размещаются в так называемой куче (Heap) - области памяти, не занятой ни кодом, ни данными, ни системой, предоставляемой программе при загрузке ОС - посредством менеджера кучи (Heap Manager). Размеры кучи, предоставляемой программе ОС задаются директивой компилятора {$M размер_стека, миним_размер_кучи, макс_ее_размер}. Миним размер вычисляется программистом исходя из его личных соображений, как, впрочем, и макс-ный. При их задании следует учитывать, что слишком маленький мин-ный размер, да еще при не совсем правильной работе приводит к Run-time error 202 - Heap allocation error, а слишком большой макс-ный размер не позволит вызывать внешние исполняемые модули.]

Доступ к динамически размещенным переменным производится с помощью указателей. Для работы с указателями существует несколько процедур и функций. B C++: операция new: int *p=new int[100] – тип и размер. B С: ф-я malloc: int*p=(int*)malloc(n*sizeof(int)); - возвращает тип void, поэтому используется операция приведения типов.

Освобождение памяти: 1. delete[] (н-р, delete []p) – если зарезервировали с помощью new. 2. ф-я free(p) – если зарезервировали с помощью malloc.

При использовании динамической памяти следует предусматривать хотя бы большинство возможных ошибок, как то: отсутствие подходящего участка памяти в куче, попытка повторного удаления удаленной динамической переменной.

[При проверке наличия доступного места в куче при работе в защищенном режиме следует учитывать, что выделение производится в два этапа: выделение локальной кучи размером HeapBlock, а затем распределение пространства по запросам. Как только текущая локальная куча исчерпывается, производится выделение новой.]

Проблема: 1) создание; 2) использование; 3) удаление.

Нарушение порядка действий этих этапов влечет к появлению ошибок.

1) попытка многократного удаления из ДП

Для того чтобы избежать ошибок повторного удаления исп-ют следующее правило: указатель, который не указывает ни на что (то есть не использовался при создании переменных или переменная, на которую он указывал уже удалена) должен иметь значение Null; перед каждым удалением любой динамической переменной необходимо производить анализ равенства указателя Null, в случае равенства - не производить удаления:

If P<>Null { Delete[]p; //free(p);

P:=null;}


Поделиться:

Дата добавления: 2015-04-18; просмотров: 48; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.005 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты