概述
众所周知在C语言标准里memmove和memcpy是两个完全不同的函数。
memcpy 只要求能做到复制就可以了,可以不满足自我重叠复制。
memmove 则更有理想,他专门从事自我重叠复制,偶尔也能客串一下memcpy函数。
我们先看一下他的定义:
可以看到他的返回类型和接收类型都是void*不定类型,因此在理论上他可以从事任意类型的内存复制。
接下来我们直接走例子看看如何完成这个函数的功能复刻:
例1:将int arr数组中的1234567转换成3456767。
首先我们回忆一下,int在内存中的样子:
如果变成
实际上是将arr+2的内容复制到arr上,而且因为这里int是四个字节构成的,所以在我们实际操作中复制1个数字便是复制了4个字节,复制5个字符就是20个字节,因此在这里count实际上是20。
那么问题又来了我这里是int啊,加20就越界了啊。
转过脑袋来再想一想,这里我们是一个字节一个字节的复制,因此实际复制的类型应该是char,所以我们首先要把dest和src的类型强制转换成(char*),然后进行逐位转换,就可以得到我们想要的答案了。
但是真的就那么简单嘛???上面解决的只是dest<src的情况。如果是dest>src呢?
这种情况下如果继续采用从前往后依次复制会出现什么事?
例2:将int arr数组中的1234567转换成1212345。
前面字节什么是一样的,不再分析,我们看一个复制的分析图
这一题的本质是将src的内容复制到dest去,如果用刚才的方法来复制得到的是
这不是我们要的答案,但为什么呢?
从前往后复制会把后面的给覆盖掉,最后就是12循环,因此在这种情况下,就不能在从前往后复制了,需要从后往前复制。
好了,接下来把两个拼起来:
void* my_memmove(void* dest, const void* src, size_t count)
{
char* ret = dest;
if (dest < src)
{
while (count--)
{
* (char*)dest = * (char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
最后
以上就是友好棒球为你收集整理的内存移动——复刻memmove的全部内容,希望文章能够帮你解决内存移动——复刻memmove所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复