memcpy和memmove均为内存拷贝函数,原型分别为:
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
当拷贝的内存存在重叠区域时,memcpy可能会发生错误,而memmove不会发生。
下图为重叠情况剖析【绿色代表重叠区域】:
重叠情况(1):
重叠情况(2):
两个函数具体实现如下:
void *memcpy(void *dst, const void *src, size_t n) /*将src 的 n 字节拷贝到dst 内存中*/
{
char *su1;
const char *su2;
for(su1 = dst, su2 = src; 0 < n; ++su1, ++su2, --n)
{
*su1 = *su2;
}
return dst;
}
void *memmove(void *dst, const void *src, size_t n) /*将scr 的 n 字节拷贝到dst 内存中*/
{
char *sc1;
const char *sc2;
sc1 = dst;
sc2 = src;
if(sc2 < sc1 && sc1 < sc2 + n)
{
for(sc1 += n, sc2 += n; 0 < n; --n) /* 从内存块的后面开始拷贝 */
{
*--sc1 = *--sc2;
}
}
else
{
for(; 0 < n; --n) /* 从内存块的前面开始拷贝 */
{
*sc1++ = *sc2++
}
}
return dst;
}
总结:
1、从源码的具体实现可以看出memmove已经包含了memcpy的功能。
2、只有在情况二的重叠情况下,即src < dst && dst < src + n (就是dst内存地址比src大,且拷贝n字节时存在重叠区域),就从内存块的后面开始拷贝
3、平时应用中,很多时候使用memcpy,因为可以确定不重叠,执行显然比memmove快