Part 1 · 1 chapters · ~8 min

Pointers and Memory

Addresses and dereferencing, pointer arithmetic, arrays as pointers, pointers to pointers, function pointers, const correctness, stack versus heap versus static storage, malloc, calloc, realloc and free, ownership conventions, and the common bugs (dangling, leaks, double free).

2

Addresses, ownership, lifetimes

code
int *bad(void) { int x = 42; return &x; }              // dangling: x dies on return (compiler warns)

char *dup_upper(const char *s) {                       // caller owns the result and must free it
    size_t n = strlen(s);
    char *out = malloc(n + 1);
    if (!out) return NULL;                             // malloc can fail: check it
    for (size_t i = 0; i <= n; i++) out[i] = (char)toupper((unsigned char)s[i]);
    return out;
}

// growing an array safely
size_t cap = 4, len = 0; int64_t *xs = malloc(cap * sizeof *xs);
if (len == cap) { int64_t *tmp = realloc(xs, (cap *= 2) * sizeof *xs); if (!tmp) { free(xs); abort(); } xs = tmp; }

// function pointers: how qsort takes a comparator
int by_amount(const void *a, const void *b) { int64_t x = *(const int64_t *)a, y = *(const int64_t *)b; return (x > y) - (x < y); }
qsort(xs, len, sizeof *xs, by_amount);
POINTERS AND MEMORY REGIONS
where values live and what a pointer holds
stacklocals, return addresses: freed on returnint *p = &xholds an addressheapmalloc / free: lives until freeddata + bssglobals and staticstextmachine code, read-only
swipe the figure sideways, or tap expand for full screen
1/4
an address
A pointer is a variable holding a memory address. *p reads or writes the value there; p + 1 moves by sizeof(*p) bytes.
a pointer holds an addressarithmetic in element sizes