pointers-memory · intermediate · ~20 min
Why memmove exists, and how to implement it without UB.
Copy n bytes from one memory region to another, getting the right result even when the two regions overlap. This is exactly what the standard memmove guarantees and memcpy does not.
Implement void *my_memmove(void *dst, const void *src, size_t n) that copies n bytes from src to dst and returns dst. The result must be correct even if dst and src overlap. No main — the grader calls it.
dst and src are byte regions (they may overlap, alias, or be disjoint). n is the number of bytes to copy (may be 0).
Returns dst. After the call, dst[0..n-1] holds the original bytes of src[0..n-1].
char buf[10] = "abcdefghij";
my_memmove(buf + 2, buf, 5) -> buf becomes "ababcdehij" (forward overlap)
char buf[10] = "abcdefghij";
my_memmove(buf, buf + 2, 5) -> buf becomes "cdefgfghij" (backward overlap)
dst == src (aliased): no-op.n == 0: no-op.memcpy or memmove.dst < src copy forward; if dst > src copy backward — that's what makes overlap safe.Most C developers learn that memcpy is faster than memmove and use it everywhere — until the day they shift bytes within the same buffer and watch their data corrupt. Implementing memmove's contract by hand cements the difference.
dst, src (may overlap or alias), and byte count n (may be 0).
Returns dst; the n bytes from src are copied into it.
Pure C. No memcpy / memmove. Handle overlap correctly.
#include <stddef.h>
void *my_memmove(void *dst, const void *src, size_t n) { /* TODO */ return dst; }
Always copying forwards (corrupts when dst > src and they overlap). Comparing dst < src with signed types (use the unsigned pointers as uintptr_t or just unsigned char *).
Aliasing; zero-length copy; one-byte copy.
O(n).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.