Why copy using pointers in loop:
for (int i = 0; i < size; i++) {
dst[i] = src[i];
}
is not the same as memmove?:
memmove(dst, src, size);
When we have overlap between src and dst?
Why copy using pointers in loop:
for (int i = 0; i < size; i++) {
dst[i] = src[i];
}
is not the same as memmove?:
memmove(dst, src, size);
When we have overlap between src and dst?
Your copying code may change some of the source elements before they are copied. The output of this code:
#include <stdio.h>
#include <string.h>
static void Copy(char *dst, const char *src, size_t size)
{
for (int i = 0; i < size; ++i)
dst[i] = src[i];
}
int main(void)
{
char b0[3] = { 'A', 'B', 'C' };
char b1[3] = { 'A', 'B', 'C' };
memmove(b0+1, b0+0, 2);
printf("After memmove: b0[1] = %c, b0[2] = %c.\n", b0[1], b0[2]);
Copy(b1+1, b1+0, 2);
printf("After Copy: b1[1] = %c, b1[2] = %c.\n", b1[1], b1[2]);
}
is:
After memmove: b0[1] = A, b0[2] = B. After Copy: b1[1] = A, b1[2] = A.
because, when i is 0, dst[0] is b1[1], so b1[1] is overwritten with 'A' before the loop increments i to 1. Then, when i is 1, src[1] is b1[1], which now contains 'A' instead of its original 'B', so the data copied to dst[1] is 'A' and not 'B'.
When we have overlap between src and dst?
If you want an example:
char str[] = "Hello world"
memmove(str, str + 6, strlen(str + 6) + 1);
It removes "Hello " from the str. Destination and source are overlapping.
Apart from the boring bug memmove(dst, src, size); -> memmove(dst, src, sizeof(*dst) * size);, then:
memmove specifically gives this guarantee (C23 7.26.2.3)
void *memmove(void *s1, const void *s2, size_t n);The
memmovefunction copiesncharacters from the object pointed to bys2into the object pointed to bys1. Copying takes place as if thencharacters from the object pointed to bys2are first copied into a temporary array ofncharacters that does not overlap the objects pointed to bys1ands2, and then thencharacters from the temporary array are copied into the object pointed to bys1.
Because memmove comes with this extra safety, it is slower than memcpy and should only be used in situations where you know or suspect that objects overlap.
A plain loop as in your example is similar to memcpy, except in your loop you actually can know that dst and src aren't overlapping. memcpy cannot know that internally.

memmove()chooses what direction to use when copying so that you're not copying a copy (of a copy (of a copy (...)). Your loop always copies from low address to high address. See ideone.com/xymcuh – pmg Commented Jan 30 at 11:19dst=src+1. The loop will plaster the first value over all the rest, while memmove... won't. – teapot418 Commented Jan 30 at 11:22dstandsrcare pointers to. – Ted Lyngmo Commented Jan 30 at 11:37