memcpy of overlapping buffers
I've done some research on this in the past... on Linux, up until fairly recently, the implementation of memcpy()
worked in a way that was similar enough to memmove()
that overlapping memory wasn't an issue, and in my experience, other UNIXs were the same. This doesn't change the fact that this is undefined behavior according to the standard, and you are just lucky that on some platforms it sometimes works -- and memmove()
is the standard-supported right answer.
However, in 2010, the glibc maintainers rolled out a new, optimized memcpy()
that changed the behavior of memcpy()
for some Intel core types where the C standard library is compiled to be faster, but no longer works like memmove()
[1]. (I seem to recall also that this is new code triggered only for memory segments larger than 80 bytes). Interestingly, this caused things like the Linux version of Adobe's Flash player to break[2], as well as several other open-source packages (back in 2010 when Fedora Linux became the first to adopt the changed memcpy()
in glibc).
- [1] https://sourceware.org/bugzilla/show_bug.cgi?id=12518
- [2] https://bugzilla.redhat.com/show_bug.cgi?id=638477
memcpy()
doesn't support overlapping memory. This allows for optimizations that won't work if the buffers do overlap.
There's not much to really look into, however, because C provides an alternative that does support overlapping memory: memmove()
. Its usage is identical to memcpy()
. You should use it if the regions might overlap, as it accounts for that possibility.