[C++]C++中memcpy和memmove的区别总结

这篇文章主要介绍了C++中memcpy和memmove的区别总结,这个问题经常出现在C++的面试题目中,需要的朋友可以参考下

变态的命名

我们在写程序时,一般讲究见到变量的命名,就能让别人基本知道该变量的含义。memcpy内存拷贝,没有问题;memmove,内存移动?错,如果这样理解的话,那么这篇文章你就必须要好好看看了,memmove还是内存拷贝。那么既然memcpy和memmove二者都是内存拷贝,那二者究竟有什么区别呢?

先说memcpy

你有没有好好的参加过一场C++笔试。让你写出memcpy的实现,这是多么常见的笔试题啊。现在,拿起你的演算纸和笔;是的,是笔和纸,不是让你在你的IDE上写。写不出来?看下面吧:



void *mymemcpy(void *dest, const void *src, size_t count)

{

    assert(dest != NULL || src != NULL);

    

    char *tmp = (char *)dest;

    char *p = (char *)src;

 

    while (count--)

    {

        *tmp++ = *p++;

    }

    return dest;

}

memcpy的实现很简单,一般在笔试时,出现写源码的题目,无非就是需要注意以下几点:

1.确定函数原型;
2.判断参数合法性;
3.逻辑实现(考虑各种情况,统称逻辑实现);
4.错误处理。

当然了,我的这个没有错误处理,也不需要错误处理。上面,我写出了memcpy的实现源码,实现原理如下图所示:

 

这样下去,上面的代码会运行的很好,如果出现下面的情况呢?

 

i、n、k的内存和J、e、l的内存地址重合了,现在再使用上面的代码进行copy时,会出现什么问题呢?你有没有想过这个问题。如果没有,那就现在想想,不急着阅读下面的内容。

然后,我再留一个问题,上面的代码中,为什么都需要将void *转换成char *呢?比如:

char *tmp = (char *)dest;

再说memmove

memmove也是用来实现内存的直接拷贝的。说起这个命名,我个人觉的多少还是有点坑的。既然memmove也是用来内存数据移动的,那就先来看看memmove的实现源码。



void *mymemmove(void *dest, const void *src, size_t count)

{

    assert(dest != NULL || src != NULL)

 

    if (dst < src)

    {

        char *p = (char *)dest;

        char *q = (char *)src;

        while (count--)

        {

            *p++ = *q++;

        }

    }

    else

    {

        char *p = (char *)dest + count;

        char *q = (char *)src + count;

        while (count--)

        {

            *--p = *--q;

        }

    }

 

    return dest;

}

memcpy和memmove的比较

从实现源码中的确能看出一些猫腻,当出现了src和dest的内存有重合的时机时,memmove的处理规则是从后往前进行copy。当然了,重合的问题,需要考虑的以下两种场合。

如图所示,当出现(1)对应的情况时,就需要先从src的头部开始复制;也就是memmove源码中的if分支,这部分源码和memcpy的实现是一致的;当出现(2)对应的情况时,就需要先从src的尾部开始复制,防止出现了覆盖现象。这就是memmove比memcpy多的一个考虑点,所以说,在实际使用时,使用memmove是比memcpy更安全的。

总结

总结到了这里,我觉的我已经把问题说清楚了。你说呢?如果你还有什么好的想法,欢迎你和我分享。

 

 

 

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FL1768317420

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值