Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Part 1: Pointers, Arrays & Memory
C

Part 1: Pointers, Arrays & Memory

Revise the C memory model, pointer arithmetic, arrays, dynamic memory allocation with malloc and free, and double pointers.

1. The memory model

C gives you raw memory — everything is bytes, addresses, and explicit lifetime.

  • Stack: automatic variables, fast, freed on return.
  • Heap: malloc/calloc/realloc, you must free, else leak.
  • Static/global: fixed lifetime (program start to end).
  • Text/code: the compiled instructions.
int *p = malloc(10 * sizeof(int));   // heap
free(p);                             // always pair with malloc

Rule: every malloc has a matching free; double-free and use-after-free are undefined behaviour.

2. Pointers — the core abstraction

  • &x address, *p dereference — int *p, &x type is int *.
  • Pointer is an address; pointing into the wrong object is UB.
  • NULL means “not a valid address”; dereference is UB/crash.
int x = 7;
int *p = &x;
*p = 9;    // x is now 9

3. Pointer arithmetic vs arrays

Pointer arithmetic scales with the pointee size:

int a[4] = {10, 20, 30, 40};
int *p = a;        // &a[0]
*(p + 2) == a[2];  // true — p+2 moves 2*sizeof(int) bytes
  • p++/p-- on pointers move one element.
  • p + 3 == &a[3]; p + 3 is out of bounds if p = &a[3] → UB.
  • Arrays decay to a pointer to first element when passed to functions (void f(int a[])int *a).

The classic questions:

  • sizeof(a) on an array gives the whole array size; on a pointer gives the pointer size.
  • int (*p)[10] — pointer to array; int *p[10] — array of pointers.

4. malloc / calloc / realloc / free

FunctionPurpose
malloc(n)n raw bytes, uninitialized
calloc(n, size)n×size, zero-initialized
realloc(p, n)resize, preserving content (may move!)
free(p)release a heap block
  • malloc returns void *; assign it to the right pointer type.
  • Always check the result against NULL before use.
  • After realloc, use the returned pointer — the old one may have moved.
int *nums = malloc(10 * sizeof(int));
if (!nums) { /* handle */ }

4. Double pointers

  • int **pp — pointer to a pointer; &p is how you change the caller’s pointer.
void init(int **pp) { *pp = malloc(100); }
int *p;
init(&p);   // p now points to heap memory
  • Used for 2D allocation, updating a pointer inside a function, and linked-list mutation.

5. Interview checkpoint

  • Pointer vs value; &, *; array decay.
  • Pointer arithmetic offsets (sized by pointee).
  • malloc/free pairing; realloc semantics.
  • NULL dereference, dangling pointers, memory leak — the three classic failure modes.

My Private Notes

Notes are auto-saved locally to this device.