C/C++ Arena

Step 7 of 10

Pointers to pointers

A pointer is itself a variable, so it has an address too. A pointer to a pointer (int **pp, read "pointer to pointer to int") stores that address. It sounds abstract, but there's one very practical reason to use it:

When a function must change which address the caller's pointer holds, it needs the address of that pointer, for the same reason a function needs &x to change an int.

#include <stdio.h>

void skip_digits(const char **p) {
    while (**p >= '0' && **p <= '9') {
        (*p)++;
    }
}

int main(void) {
    const char *text = "2024 was a leap year";
    skip_digits(&text);
    printf("[%s]\n", text);
    return 0;
}
[ was a leap year]

Unpacking the stars

Inside skip_digits, p has type const char **:

The parentheses in (*p)++ matter. *p++ would move p itself (the local copy of the address) instead of the caller's pointer, because ++ binds tighter than *.

After the call, main's text points into the middle of the same string. Nothing was copied; only the pointer moved.

Where you'll see this

Functions that allocate memory and hand it back through a parameter, functions that parse text and advance the caller's position, and linked-list code that changes the head pointer all use double pointers.

Your task

Write void advance(const char **s) that moves the caller's string pointer past any leading spaces. After advance(&p) with p pointing at " go", p should point at "go".

Challenge 2

Write int read_number(const char **s) that reads the digits at the start of *s, returns them as a number, and moves the caller's pointer past them. With p pointing at "123abc", read_number(&p) returns 123 and leaves p pointing at "abc". If there are no digits, return 0 and don't move the pointer.

Challenge 3

Write void release(int **p) that frees the memory *p points at and sets the caller's pointer to NULL, so it can't be used by mistake afterwards. It must be safe to call again on a pointer that is already NULL.

Previous: Strings through pointers Next: const and pointers