Ada: Access Types
An access type is a reference to a value — Ada's version of a pointer, but typed, tracked, and freed automatically at scope finalization. Ada has no void*, no pointer arithmetic, and no dangling-pointer bugs that survive compilation. This page covers access-to-object types, dereferencing, and the accessibility rules that make Ada's model safe.
Access to Object
new allocates a value on the heap and yields an access value pointing to it. The type of the pointer is written access T, and dereferencing uses .all:
with Ada.Text_IO; use Ada.Text_IO;
procedure Access_Demo is
type Int_Ptr is access Integer; -- a pointer-to-Integer TYPE
P : Int_Ptr := new Integer'(42); -- allocate + initialize
Q : Int_Ptr; -- null by default
begin
Put_Line (Integer'Image (P.all)); -- dereference: read 42
P.all := P.all + 1; -- dereference: write 43
if Q = null then -- null is a legitimate value
Put_Line ("Q points nowhere yet");
end if;
end Access_Demo;
Since P.all is so common, Ada lets you omit .all for field and component access: P.Field means P.all.Field. The explicit form is always available when the meaning needs emphasis.
Two Lifetimes
The memory model is the heart of the matter. Stack objects die at scope exit; heap objects live until the access type's storage pool is finalized. The rules that prevent the classic bugs:
- No dangling pointers: returning an access to a local object is rejected at compile time (accessibility check). The pointer cannot outlive its pool.
- No manual free: heap storage is reclaimed when the access type's pool is finalized. You never call
free, so use-after-free cannot be written. - No pointer arithmetic:
P + 1does not compile. If you need a walkable structure, build it as an array or a proper container. - No silent aliasing surprises: access types are visibly written in every signature —
procedure Draw (S : not null access Shape)announces its aliasing.
null Exclusion
Most access parameters and return types should never be null — say so, and the check is automatic:
procedure Print (P : not null Int_Ptr) is
begin
-- P cannot be null: the compiler (and run time, if in doubt)
-- enforces the promise at the call site.
null;
end Print;
not null is the default for access parameters in SPARK and is the recommended style in Ada too — it documents intent and removes a whole class of checks from the body.