前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原 memmove 和 memcpy的区别

原 memmove 和 memcpy的区别

作者头像
王果壳
发布2018-07-06 14:21:52
1.2K0
发布2018-07-06 14:21:52
举报
文章被收录于专栏:王硕

memcpy memmove 都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, const void *src, size_t count); void *memmove(void *dst, const void *src, size_t count);  他们的作用是一样的,唯一的区别是,当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。

第一种情况下,拷贝重叠的区域不会出现问题,内容均可以正确的被拷贝。 第二种情况下,问题出现在右边的两个字节,这两个字节的原来的内容首先就被覆盖了,而且没有保存。所以接下来拷贝的时候,拷贝的是已经被覆盖的内容,显然这是有问题的。 实际上,memcpy只是memmove的一个子集。 memmove在copy两个有重叠区域的内存时可以保证copy的正确,而memcopy就不行了,但memcopymemmove的速度要快一些,如: char s[] = "1234567890"; char* p1 = s; char* p2 = s+2;

memcpy(p2, p1, 5)与memmove(p2, p1, 5)的结果就可能是不同的,memmove()可以将p1的头5个字符"12345"正确拷贝至p2,而memcpy()的结果就不一定正确了 关于memmove的实现:

代码语言:javascript
复制
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的实现:

代码语言:javascript
复制
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;
}

下面再通过一个例子进行描述:

代码语言:javascript
复制
#include <string.h>
 
void *memmove2(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];
	printf("the src is %s\n", src);
	printf("the dest is %s\n", dest);
	printf("the temp is %s\n", temp);

    }
    return dest;
}

void *memcpy2(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;
}
 
int
main(int argc, char **argv)
{
    char s[] = "1234567890";
    char* p1 = s;
    char* p2 = s+2;
    char s1[] = "1234567890";
    char* p11 = s1;
    char* p21 = s1+2;
	
    memcpy2(p2, p1, 5);
    memmove2(p21, p11, 5);

    printf("the p2 is %s\n", p2);
    printf("the p1 is %s\n", p1);
    printf("the s is %s\n", s);
    printf("the p21 is %s\n", p21);
    printf("the p11 is %s\n", p11);
    printf("the s1 is %s\n", s1);

    return 0;
}

 输出结果为:

代码语言:javascript
复制
the src is 1214567890
the dest is 14567890
the temp is 12345
the src is 1212567890
the dest is 12567890
the temp is 12345
the src is 1212367890
the dest is 12367890
the temp is 12345
the src is 1212347890
the dest is 12347890
the temp is 12345
the src is 1212345890
the dest is 12345890
the temp is 12345
the p2 is 12145890
the p1 is 1212145890
the s is 1212145890
the p21 is 12345890
the p11 is 1212345890
the s1 is 1212345890

这里边memcpy确实发生了错误,由于是发生了重叠,其次memcpy又是对于部分数据以其他形式进行赋值,所以在一定情况下,结果就不一定正确了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档