While the memcpy copies the data byte-by-byte sequentially from source to destination, the memmove function copies the block of data to the source to the destination. The difference implies that the memcpy function can generate the repeating data results (see below) if the source data being copied happens to be overlapping with the destination data:
#include <stdio.h>
#include <string.h>
int main()
{
char src1[] = "abcdefg";
char src2[] = "abcdefg";
char *dest1;
char *dest2;
if ((dest1 = (char*)malloc(8*sizeof(char))) == NULL
|| (dest2 = (char*)malloc(8*sizeof(char))) == NULL)
exit(1);
//memcpy src1 -> dest1
memcpy(dest1, src1, 7);
printf("memcpy\tsrc1:%s\tdest1:%s\n", src1, dest1);
//memmove src2 -> dest2
memmove(dest2, src2, 7);
printf("memmove\tsrc2:%s\tdest2:%s\n", src2, dest2);
//memcpy src1 -> src1+1
memcpy(src1+1, src1, 6);
printf("memcpy\tsrc1:%s\n", src1);
//memmove src2 -> src2+1
memmove(src2+1, src2, 6);
printf("memmove\tsrc2:%s\n", src2);
free (dest1);
free (dest2);
return 0;
}
The result would be:
memcpy src1:abcdefg dest1:abcdefg
memmove src2:abcdefg dest2:abcdefg
memcpy src1:aaaaaaa
memmove src2:aabcdef
Thus, memcpy should be used with caution when the data is overlapping with each other. Specifically, the memmove works identically to memcpy if:
src_addr + length_copy < dest_addr or src_addr > dest_addrand it works reversely in the other way. So, the memmove can also be implemented as memmove2:
void * memmove2(void *dest, const void *src, size_t len)
{
if (src != dest)
{
if ((const char*)src+len < dest || (const char*)src > dest)
memcpy(dest, src, len);
else
while (len--)
*((char*)dest+len) = *((const char*)src+len);
}
return dest;
}
If we compare the following code snippets, the running time are also different between:
for (i = 0; i < 100000000; i++)
memmove(dest, src, n);
and
for (i = 0; i < 100000000; i++)
memmove2(dest, src, n);
The results depend on the relationship between dest and src, where n denotes the length of string to be copied:
dest < src | dest==src | dest > src | dest > src + n
memmove 4.020 0.321 18.070 4.036
memmove2 3.148 0.892 3.096 3.295
The running time is in second. It is obvious that while the memmove2 function outperforms the standard function in cases where dest!=src, the memmove is better when dest==src.
(Compiled using gcc 3.4.4)
No comments:
Post a Comment
(Coding && Eating) || Sleeping