C标准库string.h之--------------memcpy与memmove函数的区别剖析

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快

猜你喜欢

转载自blog.csdn.net/yunyou666666/article/details/81840958