前者更安全,多余重叠的区域的处理安全,而后者对于重叠区域的处理并不保证安全,
例如:、
char s[] = "abcdefghigk";
char* p1 = s;
char* p2 = s+3;
memcpy(p2, p1, 6)与memmove(p2, p1, 6)的结果就可能是不同的,memmove()可以将p1的头5个字符"12345"正确拷贝至p2,而memcpy()的结果就不一定正确了,因为p2的数据被覆盖了,导致src里面的数据丢失,但是memmove进行了保存,处理没有错误,从而可见,memcpy是memmove的子集,但是memcpy更快一些
memmove的实现
void *mymemmove(void *dest, const void *src, size_t n)
{
char temp[n];
int i;
char *d = dest;
const char *s = src;
for (i = 0; i < n; i++)
temp[i] = s[i];
for (i = 0; i < n; i++)
d[i] = temp[i];
return dest;
}
memcpy的实现
void *mymemcpy(void *dest, const void *src, size_t n)
{
char *d = dest;
const char *s = src;
int *di;
const int *si;
int r = n % 4;
while (r--)
*d++ = *s++;
di = (int *)d;
si = (const int*)s;
n /= 4;
while (n--)
*di++ = *si++;
return dest;
}
由此可见,memmove是一个字节一个字节的拷贝,而memcpy是4个字节四个字节的拷贝,所以快慢一目了然
对于库函数来说,由于没有办法知道传递给他的内存区域的情况,所以应该使用memmove()函数。通过这个函数,可以保证不会出现任何内存块重叠问题。而对于应用程序来说,因为代码“知道”两个内存块不会重叠,所以可以安全地使用memcpy()函数。