This creates the ability to do a form of garbage collection in Ada as illustrated and annotated in the following code:
with Ada.Text_Io; use Ada.Text_Io; procedure Alloc is type Info is record I1 : Integer; I2 : Integer; end record; type Info_Ptr is access Info; -- The Storage_Size attribute would be useless here since: -- 1) This access type will not go out of scope until program ends. -- 2) There is no way to predict a Max_Objects_To_Allocate procedure Do_Alloc is Max_Objects_To_Allocate : constant := 2; -- Maximum number of objects to be allocated before PInfo -- PInfo (the local access type) will go out of scope. -- It could be set to some large number if unknown, but -- that could potentially use up a large chunk of memory. type Pinfo is access Info; -- This access type will go out of scope at end of Do_Alloc -- procedure. for Pinfo'Storage_Size use Info'Max_Size_In_Storage_Elements * Max_Objects_To_Allocate; -- By setting the Storage_Size attribute of an access type -- to the Size of the type * max number of objects to be allocated -- it will be pointing to will cause the object pointed at to -- become deallocated when the access type goes out of scope. -- NOTE: If you try and allocate more then Max_Objects_To_Allocate, -- you will receive a STORAGE_ERROR at run time. MyInfo : Pinfo; OtherInfo : Info_Ptr; begin MyInfo := new Info; -- Allocate an Info object using the local access type (PInfo) MyInfo := new Info; -- Even though this will cause the last allocated object to be -- inaccessable, the last object will still be deallocated when -- the local access type goes out of scope. OtherInfo := new Info; -- Allocate an Info object using the non-local access type (Info_Ptr) -- Doesn't go out of scope -- The allocated Info objects pointed to by the local access type -- are deallocated here, but not those of the non-local access type. -- As a result, each iteration of this procedure produces a memory -- leak from otherInfo, while both Infos allocated to MyInfo are -- properly deallocated and therefor no leak. end Do_Alloc; begin Put("Garbage Collection Test"); New_Line; loop Do_Alloc; end loop; end;