Mastering Pointers In C

Pointers are the core of C. This is where you truly understand how computers work. From simple memory addresses to complex data structures, pointers unlock C's power and its pitfalls.

What is a Pointer?

A variable that stores a memory address. The * dereferences, the & gets the address.

pointer.c
int x = 42; // x lives at 0x1000 int *ptr = &x; // ptr holds 0x1000 printf("%d", *ptr); // Prints 42 (Dereference) printf("%p", ptr); // Prints 0x1000 (Address)
Address 0x2000
ptr
0x1000
→ Points To →
Address 0x1000
x
42
⚠ Common Mistake: int* ptr1, ptr2; declares ptr1 as a pointer, but ptr2 as a regular integer!
Correct: int *ptr1, *ptr2;

Pointer Arithmetic

Moving through memory. Pointers move by the size of the type they point to.

arithmetic.c
int arr[] = {10, 20, 30}; int *ptr = arr; // Points to 10 (0x1000) ptr++; // Moves 4 bytes (sizeof int) // Now at 0x1004 (20) ptr += 1; // Now at 0x1008 (30)

Pointers vs Arrays

Arrays decay into pointers, but they are not identical.

Array Decay

int arr[5]; int *ptr = arr; // arr decays to &arr[0]

The Difference

sizeof(arr) = 20 (5*4) sizeof(ptr) = 8 (ptr size) arr = ptr; // ERROR!

Double Pointers (int **)

A pointer that stores the address of another pointer. Used for changing pointer targets.

void allocate(int **p) { *p = malloc(sizeof(int)); } int main() { int *ptr = NULL; allocate(&ptr); // Pass address of ptr }

Generic Pointer (void *)

Can point to any type, but cannot be dereferenced without casting.

int x = 10; void *generic = &x; // printf("%d", *generic); // ERROR: Size unknown printf("%d", *(int*)generic); // Cast first

Const Correctness

Protecting data integrity.

Pointer to Const

const int *ptr; // Cannot change value (*ptr = 5 ❌) // Can change address (ptr = &y ✅)

Const Pointer

int * const ptr; // Can change value (*ptr = 5 ✅) // Cannot change address (ptr = &y ❌)

Function Pointers

Storing code addresses. Enables callbacks.

int add(int a, int b) { return a+b; } int main() { // Pointer to function taking 2 ints, returning int int (*func_ptr)(int, int) = add; printf("%d", func_ptr(2,3)); // Calls add(2,3) }

Real World Crashes

Why your C program segfaults.

1. Uninitialized Pointer

int *p; *p = 10; // CRASH! Random address.

2. NULL Dereference

int *p = NULL; *p = 10; // CRASH! Address 0x0.

3. Use After Free

free(p); *p = 10; // CRASH! Memory gone.

4. Return Stack Address

int* bad() { int x = 5; return &x; // DANGEROUS! x dies on return. }