pointers-memory · intermediate · ~25 min
Two-level allocation; matching free order.
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.
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.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.
alloc_2d returns the int ** (usable as a[i][j]), or NULL on allocation failure. free_2d returns nothing.
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);
rows or cols == 0: must not crash; free_2d on the result is safe.calloc so memory is zeroed.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.
rows, cols (small sizes, may be 0); free_2d also takes the matching rows.
alloc_2d returns int ** (or NULL on failure); free_2d returns nothing.
Use calloc to zero-initialize. Free rows before the outer array.
#include <stddef.h>
int **alloc_2d(size_t rows, size_t cols);
void free_2d(int **a, size_t rows);
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).
rows or cols == 0 — must not crash. Allocation failure mid-way — clean up partial state.
O(rows * cols) to zero-init.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.