我是靠谱客的博主 友好棒球,最近开发中收集的这篇文章主要介绍内存移动——复刻memmove,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

众所周知在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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部