TIL: memcpy vs memmove

2022-05-20 00:00:00 +0000 UTC

When working with dynamically allocated objects of type other than char* the mem functions are used. memcpy has this prototype:

void* memcpy(void* dest, const void* src, size_t n);

A call to memcpy copies n bytes from src to dest. However there is a caveat: many implementations have subtle bugs involving data reordering if src and dest overlap. Per the man page:

Failure to observe the requirement that the memory areas do not overlap has been the source of significant bugs. (POSIX and the C standards are explicit that employing memcpy() with overlapping areas produces undefined behavior.) Most notably, in glibc 2.13 a performance optimization of memcpy() on some platforms (including x86-64) included changing the order in which bytes were copied from src to dest.

To copy data where an overlap is possible, the function that must be used is instead memmove. The memmove prototype is:

void* memmove(void* dest, const void* src, size_t n);

The prototypes are identical but the implementations differ. Per the man page for memmove on my Debian machine:

(…) The memory areas may overlap: copying takes place as though the bytes in src are first copied into a temporary array that does not overlap src or dest (…)

Source: man memcpy and man memmove.

Tags: til c