The man page on memcpy is clear.
The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas must not overlap. Use memmove(3) if the memory areas do overlap.
In days gone by the memcpy would be done by a simple loop copying bytes from src to dst until length runs out. e.g. while(len--)*dst++=*src++; or some such, but probably in assembler.
So a classic case of copying a block of data back a few bytes, e.g. memcpy(data,data+1,len) would be fine.
Unfortunately the warning of The memory areas must not overlap. is not to be ignored.
You will get away with ignoring it a lot, and that is the problem! Whether you get away with it depends on a lot of things. Version of C libraries and even version of the compiler, the specific alignment of the points you are moving data to and from, the length you are moving, and probably more factors I cannot think of.
So things may work 100% until next recompiled, or simply until run on a new machine. Worse, they may work most of the time, but not quite all.
The reason is that a memcpy can be carefully optimised. For example, on an ARM you can load a whole load of registers in one go and then store a whole load of registers in one go. It may be more optimal for it to start copying from the end and work backwards, for example. The specification of memcpy not permitting overlapping areas allows for all number of optimisations to be performed in the implementation.
On the other hand memmove has to allow for overlapping areas.
The memmove() function copies n bytes from memory area src to memory area dest. 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, and the bytes are then copied from the temporary array to dest.
So, always be careful to use memmove if you cannot be sure the memory areas do not overlap.
P.S. Someone pointed out I am getting forgetful. See http://www.revk.uk/2011/02/memcpy-minor-duh-moment-on-my-part-and.html