Garbage collection using the Storage_Size attribute

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;

      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;


   Put("Garbage Collection Test"); New_Line;



   end loop;


Contributed by: David Botton
Contributed on: November 24, 1998
Last updated on: April 25, 1999
License: Public Domain