Chapter 11 — Key Takeaways (Pointers, Targets, and Dynamic Data Structures)
A one-page reference. The whole chapter reduces to two sentences: => moves the alias and = writes the
value; and prefer allocatable, reaching for pointer only when you truly must.
The two assignments (memorize this first)
| Statement |
Name |
Effect |
p => a |
pointer assignment |
makes p an alias for a; changes what p refers to, no value copied |
p = a |
value assignment |
if p is associated, copies a's value through p into its target |
Confusing these corrupts data silently. => relocates the sticky note; = writes on the page under it.
Declaring pointers and targets
real(dp), target :: a ! a may be pointed at
real(dp), pointer :: p => null() ! ALWAYS initialize: never leave a pointer undefined
p => a ! associate
- A pointer may only point at an object with the
target attribute (or another pointer).
- An object without
target is assumed un-aliased, which the compiler optimizes around — so do not add
target unless you need it.
Association status and the two hazards
| Status |
Meaning |
associated(p) |
| associated |
valid alias for a target / allocated memory |
.true. |
| disassociated |
explicitly points at nothing (nullify, => null()) |
.false. |
| undefined |
never initialized — do not query |
undefined behavior |
| Hazard |
What it is |
Fix |
| Undefined pointer |
never given a status |
initialize => null() / nullify at birth |
| Dangling pointer |
aliases freed/out-of-scope memory; may still look associated |
nullify every alias after deallocate |
Intrinsics and statements introduced
| Name |
What it does |
associated(p) |
is p associated with any target? (illegal on an undefined pointer) |
associated(p, tgt) |
is p associated with this specific target? |
nullify(p) |
set p to the disassociated state |
=> null() |
initialize/assign a pointer to disassociated |
is_contiguous(a) |
does a actually occupy contiguous memory? (Fortran 2008) |
move_alloc(from, to) |
$O(1)$ transfer of an allocation; leaves from deallocated |
allocatable vs pointer — the decision
Prefer allocatable when… |
Reach for pointer only when… |
| you own the data (the usual case) |
you must alias an existing object |
| you want automatic deallocation |
you need a genuine linked structure (and an index-array won't do) |
| you want no dangling, no leaks |
you need a polymorphic container (class, select type) |
| you want full no-aliasing optimization |
you need a callback (procedure pointer) |
| the array is a derived-type component |
you must handle a C address (type(c_ptr), c_f_pointer) |
The rule: prefer allocatable; use pointer only for aliasing, links, polymorphism, callbacks, or
C interop.
Linked structures — the safe teardown
p => head
do while (associated(p))
nxt => p%next ! SAVE next before...
deallocate(p) ! ...freeing the node
p => nxt
end do
nullify(head)
- Never read a node after you deallocate it.
- In Fortran, prefer an array or an index-based structure over raw pointer links — contiguity prefetches
and vectorizes; pointer-chasing does neither.
The contiguous attribute
real(dp), pointer, contiguous :: col(:) ! promise: a solid block
real(dp), intent(in), contiguous :: u(:,:) ! same promise on a dummy (Ch. 29)
- A promise the array is one unbroken block (no strides) — licenses vectorization; changes no results.
- Column-major fact: a column
a(:,j) is contiguous; a row a(i,:) is not.
- Break the promise (aim it at a strided slice) and the program is nonconforming.
Procedure pointers (callbacks) — one line
procedure(unary), pointer :: f => null()
f => square; y = f(3.0_dp) ! choose behavior at run time
Numbers and rules worth remembering
- Growable array =
allocatable store + logical-size n, doubled on overflow → $O(1)$ amortized
append (arithmetic growth would be $O(n)$).
- A linked list of $n$ int nodes (16 B/node) costs ~4× the memory of a plain 4-byte-int array.
- After
deallocate, every alias must be nullified — the language tracks only the one you named.
Project piece added this chapter
Not new code for the solver — a justified decision: field_t stores its grid as
real(dp), allocatable :: u(:,:), never a pointer, for automatic deallocation, no dangling, and the
no-aliasing optimization the Chapter 24 stencil relies on (foreshadowing
Chapter 27). contiguous is applied to
a dummy argument, not the field itself, when Chapter 29 optimizes the sweep.