memmove

  在介绍memcpy时,我们简单的实现了对memcpy的模拟,但是我们好像并没有想过如果拷贝数据与被拷贝数据之间有重叠时,我们自己实现的模拟memcpy函数还能正确拷贝吗?

   实际上我们自己实现的memcpy函数终究还是不够全面的(库函数中的memcpy函数可能会成功这就是好比60分及格与80分以上优秀的差距了),平时拷贝有重叠的数据时我们一般使用的是memmove函数。 

一、简介memmove

    与memcpy函数一样,memmove函数也是库函数<string.h>中的,也是从source位置开始向后复制num个字节的数据到destination所处的内存位置。实际上两者之间的差别也就是memmove函数处理的源内存块和目标内存块是可以重叠的。

这里我们将arr1往后20个字节的数据复制到arr1+2的位置。


二、模拟实现memmove

 假设我们要将1,2,3,4,5拷贝到3,4,5,6,7所在的内存块,我们想要的是

但是实际上

    这是因为我们从前向后把1拷贝到3的位置,2拷贝到4所在的位置,那么这时3的位置的内容已经是1,那么拷贝到5的位置的数据就是1而不是3。开始将原始区域的内容复制到目标区域的时候,会将后半部分的原始区域的数据进行覆盖,造成原始数据的丢失。

    

那么我们如果从后向前复制呢?将5拷贝到7所在的位置,4拷贝到6所在的位置,以此类推可以顺利的将数据拷贝。

那么什么时候要从后向前拷贝呢?什么时候从前向后拷贝是合适的呢? 

 

所以,当dest<=src的时候要从前向后拷贝,其他的时候从后向前拷贝(为了方便,其实也可以分为三份,dest<=src及dest与src无重合时可以从前向后,有重合时从后向前)。

具体代码的实现:

这里我们是分情况讨论的:
当dest<=src时 :

          数据从前向后拷贝的,因为不知道拷贝的时什么内容所以我们将dest与src都强转为char*类型,一个字节一个字节的去拷贝。拷贝完成后dest+1,src+1(跳到下一个字节)。

当dest>src时:


           数据从后向前拷贝,这时我们将dest+num跳到要拷贝位置的末尾,再减1回到最后一位数的起始字节。src同理。(注意!dest这时被强转为char*类型,而1还是int类型)

           将src内的数据拷贝到dest,然后因为我们是从后向前存储,因此不是跳到下一个字节而是找到上个一个字节,所以dest-1,src-1;

          最后返回dest即可,但是因为dest这时已经不在起始位置,因此我们定义一个void*类型的变量ret(因为不知到会是什么类型的数据)保存dest,然后 return ret即可。

   将情况分为三份:

    dest<=src时,           从前向后

    dest与src无重合时,从前向后

    dest与src有重合时,从后向前,

     其实也是按从后向前还是从前向后的情况讨论的

     dest<=src及dest与src无重合时讨论一种情况,有重合时从后向前一种情况

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值