Проблемы обусловленные применением ссылочных типов
Несмотря на то, что в сравнении с традиционными указателями ссылочные типы Ады обладают свойствами которые помогают обеспечить надежность разрабатываемого программного обеспечения, нельзя не упомянуть о проблемах которые возникают при использовании как указателей, так и ссылочных типов.
Рассмотрим следующий пример:
declare
type Person_Name is new String (1 .. 4); type Person_Age is Integer range 1 .. 150; type Person is record Name : Person_Name; Age : Person_Age; end record; X : Person_Ptr := new Person'("Fred", 27); Y : Person_Ptr := new Person'("Anna", 20); begin X := Y; -- ***** Y.all := Person'("Sue ", 34); Put(X.Name); end; |
В этом примере, основной интерес для нас представляет строка помеченная звездочками.
В ней ссылочному объекту X присваивается значение ссылочного объекта Y, а не значение объекта, на который ссылается Y.
После этого оба ссылочных объекта, - и X, и Y, - ссылаются на один и тот же объект, размещенный в области динамической памяти.
Первым интересным моментом является то, что теперь изменение объекта на который ссылается переменная Y будет неявно изменять объект на который ссылается переменная X
(такое неявное изменение часто называют "побочным эффектом").
Поэтому в результате выполнения кода этого примера будет выводиться строка "Sue ".
Следует заметить, что при разработке реальных программ, работающих со ссылочными типами, необходимо уделять должное внимание эффектам подобного вида, поскольку они могут быть первопричиной странного поведения программы, а в некоторых случаях могут вызвать аварийное завершение работы программы.
Вторым интересным моментом является то, что после выполнения присваивания ссылочному объекту X значения ссылочного объекта Y, теряется ссылка на объект, на который до присваивания ссылался ссылочный объект X.
При этом, сам объект продожает благополучно располагаться в области динамической памяти (такой эффект называют "утечкой памяти").
Следует заметить, что при интенсивном использовании ссылочных типов, утечка памяти может привести к тому, что все доступное пространство области динамической памяти будет исчерпано.
После этого, любая попытка разместить какой-либо объект в области динамической памяти приведет к ошибке Storage_Error.