Pointers & Memory · intermediate · ~10 min

Double pointers

Change a caller-owned pointer without changing its pointed-to integer.

Overview

A pointer is itself a variable. To let a function change a pointer owned by its caller, pass the address of that pointer. This adds one level of indirection; it does not require a linked list or an allocation.

Core concepts

If p is an int *, then &p has type int **. For int **pp = &p, *pp is the pointer stored in p, while **pp is the integer it points to.

Assigning through *pp changes the caller's pointer. Assigning through **pp changes the target integer. A pointer swap should exchange pointer values without modifying either target. The two outer pointers must be valid; their inner values can be NULL when you are only swapping those values.

Lesson

A pointer is itself a variable. To let a function change a pointer owned by its caller, pass the address of that pointer. This adds one level of indirection; it does not require a linked list or an allocation.

Code examples

#include <stdio.h>
void redirect(int **pp, int *target) { *pp = target; }
int main(void) {
    int x = 1, y = 9;
    int *p = &x;
    redirect(&p, &y);
    printf("%d %d\n", *p, x);
    return 0;
}

Expected output on a successful allocation, where applicable:

9 1

Line by line

The function receives the address of p and replaces the value stored there with the address of y. x is untouched. Dereferencing the updated p now reads y.

Practice tasks

  1. Label pp, *pp, and **pp in a diagram.
  2. Complete Dereference twice.
  3. Implement Swap two pointers.
  4. Explain the bug in a swap that exchanges **a and **b: it changes the target values instead of the pointer variables.

Summary

Use one dereference to change a caller's pointer and two to access its target. Pointer ownership and target ownership are separate concerns.

Practice with these exercises