Is the memory freed the same way after the declare block (and before the end of the procedure of course) in both cases:
procedure allocation is
type T_Integer_Access is access Integer;
begin
declare
P : T_Integer_Access;
begin
P := new Integer'(5);
end;
end;
procedure allocation is
begin
declare
type T_Integer_Access is access Integer;
P : T_Integer_Access;
begin
P := new Integer'(5);
end;
end;
Put another way, has the access type declaration an effect on memory deallocation?
There’s a good chance that the storage pool (memory arena) from which objects of type T_Integer_Access
is allocated won’t be freed ever, since you haven’t defined your own storage pool; AARM 13.11 says at (2.a)
By default, the implementation might choose to have a single global storage pool, which is used (by default) by all access types, which might mean that storage is reclaimed automatically only upon partition completion. Alternatively, it might choose to create a new pool at each accessibility level, which might mean that storage is reclaimed for an access type when leaving the appropriate scope. Other schemes are possible.
-- in other words, it’s not specified by the language.
I think it’s very unusual to define access-to-object types other than at library level. I’ve never done it, so I don’t know what compilers actually do.
Update:
valgrind doesn’t run on macOS Sierra, so I tried on Debian jessie with GNAT GPL 2016; both your Allocation
s definitely leak memory.
Storage pools are finalizable, so you could implement your own; or you might look at, for example, Deepend.
While the location of the access type declaration in your example does not affect how memory is allocated or deallocated, the chosen storage pool may do so. In either variation of procedure allocation
, the execution of the enclosed block statement proceeds as follows:
The elaboration of its declarative part causes space to be allocated for a value of an access type; in this case, the value may be thought of conceptually as a pointer or reference to an Integer
; the space for the value is typically allocated on an execution stack.
The execution of its handled sequence of statements causes the evaluation of an allocator that creates an object; in this case, the object is an Integer
having the value 5
; the space for the object is typically allocated from a pool of memory supplied by the host operating system.
In either case, when the block statement concludes, the space allocated for the access value is reclaimed, but the space allocated for the Integer
value may remain. See Ada Programming/Types/access for additional details on reclaiming allocated storage.