"Адское" программирование Ada-95 -Компилятор GNAT



              

Освобождение пространства динамической памяти



Освобождение пространства динамической памяти

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

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

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

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

  • выполнение явного освобождения пространства динамической памяти в программе

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

Если вам необходимо освободить память (подобно тому как это делает системный вызов free в UNIX), то вы можете конкретизировать настраиваемую процедуру Ada.Unchecked_Deallocation.Эта процедура называется непроверяемой (unchecked) поскольку компилятор не осуществляет проверку отсутствия ссылок на освобождаемый объект.Таким образом, выполнение этой процедуры может привести к появлению "висячих" ссылок.

generic type Object(<>) is limited private; type Name is access Object;procedure Ada.Unchecked_Deallocation(X : in out Name); pragma Convention(Intrinsic, Ada.Unchecked_Deallocatoin);

Для показанного ранее ссылочного типа Element_Ptr, значения которого ссылаются на объекты типа Element это может быть конкретизировано следующим образом:

procedure Free is new Ada.Unchecked_Deallocation(Object => Element, Name => Element_Ptr);

Теперь, можно написать рекурсивную процедуру Free_List, которая будет удалять список, состоящий из объектов типа Element.Начало списка будет указываться параметром процедуры Free_List, а для непосредственного удаления объекта типа Element процедура Free_List будет использовать процедуру Free:

with Free;procedure Free_List (List_Head: in out Element) is begin if List_Head.Next /= null Free_List(List_Head.Next); -- рекурсивный вызов end if; Free(List_Head); end Free_List;

В результате, для удаления показанного ранее списка объектов типа Element начало которого указывается переменной Head_Element можно выполнить следующее:

. . . Free_List(Head_Element); . . .

Следует напомнить, что в рассмотренном нами списке для последнего элемента (узла) значение ссылки Next было равно null.

При описании ссылочного типа Element_Ptr, может быть использована директива компилятора Controlled:

. . . type Element_Ptr is access Element; pragma Controlled(Element_Ptr); . . .

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









Содержание  Назад  Вперед