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
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