Chapter 14 Key Takeaways: Pointers and Dynamic Memory

Core Concepts

  1. A pointer is an address. A pointer variable stores the memory address of another value. It does not contain the data itself — it contains the location where the data resides.

  2. Stack vs. Heap. The stack holds local variables with automatic lifetimes tied to their scope. The heap holds dynamically allocated data with lifetimes controlled by the programmer via New and Dispose.

  3. Pointer variables live on the stack; the data they point to lives on the heap. This distinction is fundamental to understanding pointer behavior.

  4. New(p) allocates heap memory and stores its address in p. The allocated block is uninitialized — always assign a value before reading.

  5. Dispose(p) frees heap memory but does NOT set p to nil. You must do that yourself as a defensive measure.

  6. Dereferencing (p^) follows the pointer to the data. For records: p^.FieldName. Never dereference a nil or uninitialized pointer.

  7. @x returns the address of variable x. Do not return the address of a local variable from a function — it becomes a dangling pointer when the function returns.

The Four Pointer Bugs

Bug Cause Prevention
Memory leak New without matching Dispose Match every allocation with a deallocation
Dangling pointer Using a pointer after Dispose Set to nil after Dispose; ownership discipline
Nil dereference Dereferencing a nil pointer Check p <> nil before p^
Double free Dispose called twice on same block Set to nil; single-owner rule

The Ownership Principle

Every heap-allocated block has exactly one owner — one pointer responsible for eventually calling Dispose. Other pointers may temporarily reference (borrow) the same block, but they do not own it and must not free it.

Key Syntax Reference

Operation Pascal Syntax Purpose
Declare pointer type PFoo = ^TFoo; Define a typed pointer
Allocate New(p); Claim heap memory
Deallocate Dispose(p); Return heap memory
Dereference p^ Access the pointed-to value
Address-of @x Get address of existing variable
Null pointer nil Represents "points to nothing"
Null check if p <> nil then Guard against nil dereference

Linked Structures

  • A node is a record containing data and a pointer to the next node.
  • A linked chain is a sequence of nodes connected by Next pointers, terminated by nil.
  • Traversal pattern: while Current <> nil do begin ... Current := Current^.Next; end;
  • Deallocation pattern: Save next, free current, advance. Repeat until nil.

Transferable Skills

  • The pointer mental model (addresses, indirection, ownership) applies to every programming language.
  • Pascal's type-safe pointers build habits that prevent bugs in C, C++, Java, Python, and Rust.
  • The progression Pascal -> C -> C++ -> Rust is one of increasing enforcement of the same fundamental discipline.

PennyWise Progress

In this chapter, PennyWise transitioned from a fixed-size array to a dynamically allocated linked list of expense records. The list can now grow without limit, and all memory is properly freed when the program ends.