RM 95 13.11(18) says:
"If Storage_Size is specified for an access type, then the Storage_Size of this pool is at least that requested, and the storage for the pool is reclaimed when the master containing the declaration of the access type is left."
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;
|