A pointer to a pointer lets a helper update which object another pointer names.

pointer slot A pointer-to-pointer receives the address of a pointer variable, not the address of the final value.
retargeting Writing through the pointer slot changes the caller's pointer.

Pointer To Pointer

left
pointer_to_pointer.c
Replay: real traced execution (multi-file project)
#include <stdio.h>

static void choose_larger(int **slot, int *left, int *right) {
    if (*right > *left) {
        *slot = right;
    } else {
        *slot = left;
    }
}

int main(void) {
    int left = 4;
    int right = 7;
    int *selected = &left;

    choose_larger(&selected, &left, &right);

    printf("selected=%d\n", *selected);
    return 0;
}
#include <stdio.h>

static void choose_larger(int **slot, int *left, int *right) {
    if (*right > *left) {
        *slot = right;
    } else {
        *slot = left;
    }
}

int main(void) {
    int left = 2;
    int right = 7;
    int *selected = &left;

    choose_larger(&selected, &left, &right);

    printf("selected=%d\n", *selected);
    return 0;
}
#include <stdio.h>

static void choose_larger(int **slot, int *left, int *right) {
    if (*right > *left) {
        *slot = right;
    } else {
        *slot = left;
    }
}

int main(void) {
    int left = 9;
    int right = 7;
    int *selected = &left;

    choose_larger(&selected, &left, &right);

    printf("selected=%d\n", *selected);
    return 0;
}
  1. left ← 4, right ← 7, selected ← ⟨addr A⟩

    11int main(void) {12    int left→ 4 = 4; //@left=9, 213    int right→ 7 = 7;14    int *selected→ ⟨addr A⟩ = &left4;1516    choose_larger(&selected⟨addr A⟩, &left4, &right7);
  2. static void choose_larger(int **slot, int *left, int *right)

    3static void choose_larger(int **slot⟨addr B⟩, int *left⟨addr A⟩, int *right⟨addr C⟩) {4    if (*right > *left) {
  3. if (*right > *left)

    3static void choose_larger(int **slot, int *left, int *right) {4    if (*right⟨addr C⟩ > *left⟨addr A⟩) {5        *slot⟨addr B⟩ = right⟨addr C⟩;6    } else {
  4. selected ← ⟨addr C⟩

    16    choose_larger(&selected→ ⟨addr C⟩, &left4, &right7);1718    printf("selected=%d\n", *selected⟨addr C⟩);19    return 0;20}
    outputselected=7
  1. left ← 2, right ← 7, selected ← ⟨addr A⟩

    11int main(void) {12    int left→ 2 = 2;13    int right→ 7 = 7;14    int *selected→ ⟨addr A⟩ = &left2;1516    choose_larger(&selected⟨addr A⟩, &left2, &right7);
  2. static void choose_larger(int **slot, int *left, int *right)

    3static void choose_larger(int **slot⟨addr B⟩, int *left⟨addr A⟩, int *right⟨addr C⟩) {4    if (*right > *left) {
  3. if (*right > *left)

    3static void choose_larger(int **slot, int *left, int *right) {4    if (*right⟨addr C⟩ > *left⟨addr A⟩) {5        *slot⟨addr B⟩ = right⟨addr C⟩;6    } else {
  4. selected ← ⟨addr C⟩

    16    choose_larger(&selected→ ⟨addr C⟩, &left2, &right7);1718    printf("selected=%d\n", *selected⟨addr C⟩);19    return 0;20}
    outputselected=7
  1. left ← 9, right ← 7, selected ← ⟨addr A⟩

    11int main(void) {12    int left→ 9 = 9;13    int right→ 7 = 7;14    int *selected→ ⟨addr A⟩ = &left9;1516    choose_larger(&selected⟨addr A⟩, &left9, &right7);
  2. static void choose_larger(int **slot, int *left, int *right)

    3static void choose_larger(int **slot⟨addr B⟩, int *left⟨addr A⟩, int *right⟨addr C⟩) {4    if (*right > *left) {
  3. else

    5    *slot = right;6} else {7    *slot⟨addr B⟩ = left⟨addr A⟩;8}
  4. choose_larger(&selected, &left, &right);

    16    choose_larger(&selected⟨addr A⟩, &left9, &right7);1718    printf("selected=%d\n", *selected⟨addr A⟩);19    return 0;20}
    outputselected=9