memcpy()和memmove()函数的区别是在于对内存重叠的情况的处理。
memcpy()对内存重叠不做任何处理,而memmove()在内存重叠时采用从尾部复制。
以上,是官方的解释,也是各个博客的解释。肯定没问题。先贴一下两个函数的实现。
void* memcpy(void*dest, constvoid*src, size_tn)
{
char*dp = dest;
constchar*sp = src;
while (n--)
*dp++ = *sp++;
return dest;
}
void* memmove(void*dest, constvoid*src, size_tcount)
{
char*tmp;
constchar*s;
if (dest <= src) {
tmp = dest;
s = src;
while (count--)
*tmp++ = *s++;
} else {
tmp = dest;
tmp += count;
s = src;
s += count;
while (count--)
*--tmp = *--s;
}
return dest;
}
内存重叠的情况有两种:
一:
二:
如果按照memcpy()和memmove()的源码分析,第一种情况的内存重叠将导致memcpy()复制出现abababgh的情况,但实际在测试时却出现ababcdgh,也就是说memcpy()和memmove()的情形一致。
测试代码如下:
输出:
这就有点奇怪了。在网上找了半天,多是谈到内存重叠为止,终于在stackoverflow上找到类似的情况。stackoverflow链接
stackoverflow上这篇的评论的例子同样都跑了一下,皆是两个函数的输出一致。
但是,有个回答倒是解释了我的疑惑。原文是这样的:
In particular, depending on the platform, it's possible that memcpy
is implemented exactly the same way as memmove
. That is, whoever wrote the compiler didn't bother writing a unique memcpy
function.
也就是说,不同编译器对memcpy的实现是不一样的,在某些平台上,memcpy()和memmove()的实现可能是一样的。当然,我也用了不同的平台跑了一下代码,虽然结果仍是一样,但这个解释还是说得通的。
如果大家对这种情况有更加完美的答案,望不吝赐教。