pointers-memory · intermediate · ~20 min
Why memmove exists, and how to implement it without UB.
Implement void *my_memmove(void *dst, const void *src, size_t n) that copies n bytes from src to dst correctly even when the regions overlap.
The contract matches the standard memmove:
dst.dst and src overlap (this is what distinguishes it from memcpy).The trick:
dst < src, copy forwards (low addresses first).dst > src, copy backwards (high addresses first).dst == src or n == 0, do nothing.char buf[10] = "abcdefghij";
my_memmove(buf + 2, buf, 5); // shift forward by 2
// buf -> "ababcdehij" — the overlap is safely handled
char buf[10] = "abcdefghij";
my_memmove(buf, buf + 2, 5); // shift backward by 2
// buf -> "cdefgfghij"
dst == src: no-op.n == 0: no-op.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, byte count.
Returns dst.
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.