pointers-memory · intermediate · ~30 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.Optional project: combine ownership, bounds, and failure handling across an API.
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.
Return NULL for zero dimensions, unrepresentable row/table sizes, or allocation failure; release every successfully allocated row on partial failure. Caller uses free_2d with the original row count; free_2d(NULL, rows) is a no-op.
#include <stddef.h>
int **alloc_2d(size_t rows, size_t cols);
void free_2d(int **a, size_t rows);
Freeing the table before its rows or forgetting partial-allocation cleanup.
Zero dimension; one cell; non-square matrix; failure after some rows; all cells initially zero.
O(rows * cols) to zero-init.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.