pointers-memory · intermediate · ~25 min

Allocate and free a dynamic 2-D array

Two-level allocation; matching free order.

Challenge

Build a dynamically allocated 2-D integer array using the "array of pointers" layout: an outer array of row pointers, each pointing to its own row of ints. Then tear it down in the matching order.

Task

Implement two functions (no main — the grader calls them):

  • int **alloc_2d(size_t rows, size_t cols) — allocate an array of rows int* pointers, each pointing to a cols-element int array. Every element starts at 0.
  • void free_2d(int **a, size_t rows) — free every row, then the outer array.

Input

rows and cols are small sizes (may be 0). free_2d receives a pointer returned by alloc_2d (or NULL) and the same rows count.

Output

alloc_2d returns the int ** (usable as a[i][j]), or NULL on allocation failure. free_2d returns nothing.

Example

int **m = alloc_2d(3, 4);
m[2][3]   ->   0          (zero-initialized)
m[1][2] = 99;             (writable; other cells stay 0)
free_2d(m, 3);

Edge cases

  • rows or cols == 0: must not crash; free_2d on the result is safe.
  • Allocation failure mid-way: free the partially built structure and return NULL.

Rules

  • Use calloc so memory is zeroed.
  • Free rows before the outer array.

Why this matters

True 2-D allocation in C is its own subject. Two conventions exist: 'array of pointers' (rough but flexible) and 'flat with stride math' (cache-friendly). Knowing both shapes prevents endless segfaults.

Input format

rows, cols (small sizes, may be 0); free_2d also takes the matching rows.

Output format

alloc_2d returns int ** (or NULL on failure); free_2d returns nothing.

Constraints

Use calloc to zero-initialize. Free rows before the outer array.

Starter code

#include <stddef.h>
int **alloc_2d(size_t rows, size_t cols);
void free_2d(int **a, size_t rows);

Common mistakes

Freeing the outer array first, leaking the rows; forgetting to free a NULL-marked tail; allocating rows*cols ints in one block but accessing them as a[i][j] (only works if you actually set up the pointers).

Edge cases to handle

rows or cols == 0 — must not crash. Allocation failure mid-way — clean up partial state.

Complexity

O(rows * cols) to zero-init.

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.