Difference Between memcpy and memmove in C
In the C programming language, both memcpy and
memmove are standard library functions used to copy a
specified number of bytes from a source memory block to a destination
memory block. The fundamental distinction between them lies in how they
handle overlapping memory regions. While memcpy assumes
that the source and destination do not overlap and results in undefined
behavior if they do, memmove guarantees safe copying even
when the two buffers share memory addresses.
The Behavior of memcpy
The function signature for memcpy is defined as:
void *memcpy(void *dest, const void *src, size_t n);In modern C (C99 and later), both pointer arguments are marked with
the restrict keyword, which informs the compiler that
dest and src point to distinct,
non-overlapping memory regions.
Because memcpy assumes independence between the buffers,
it typically performs the copy in a single direction (usually from
lowest address to highest address). If the destination buffer starts
inside the source buffer, copying forward overwrites source data that
has not yet been read, leading to data corruption and undefined
behavior.
Because it does not perform safety checks or adjust its copy
strategy, memcpy can be heavily optimized by compilers
using specialized CPU instructions, making it marginally faster than
memmove.
The Behavior of
memmove
The function signature for memmove is defined as:
void *memmove(void *dest, const void *src, size_t n);Unlike memcpy, memmove does not use the
restrict keyword and is explicitly designed to handle
overlapping memory areas safely. The C standard dictates that
memmove must copy the bytes as if they are first copied to
a temporary array that does not overlap src or
dest, and then copied from that temporary array to
dest.
In practice, standard library implementations avoid the overhead of
allocating temporary memory. Instead, memmove compares the
memory addresses of dest and src to determine
the direction of the copy:
- When
dest < src: The destination starts before the source. The function copies bytes sequentially from the beginning to the end (left to right). Even if the end ofdestoverlaps the start ofsrc, the reading pointer is always ahead of the writing pointer, preventing corruption. - When
dest > src: The destination starts inside the source. A standard left-to-right copy would overwrite unread source bytes. To prevent this,memmovecopies bytes in reverse, starting from the end of the buffers down to the beginning (right to left).
When to Use Each Function
- Use
memcpywhen you are certain that the source and destination blocks reside in completely separate memory locations. This is common when copying between two distinct variables, structures, or separately allocated buffers. - Use
memmovewhenever there is a possibility that the memory blocks overlap, such as shifting elements within the same array, implementing sliding windows, or reallocating memory in-place.