栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

memcpy、memmove函数的实现与讲解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

memcpy、memmove函数的实现与讲解

memcpy函数和memmove函数都是内存操作函数,在平时编程的时候,经常需要对一段内存进行操作例如该值或者拷贝。这两个函数对我们很有帮助。

一、memcpy函数概括:

memcpy
Copies characters between buffers.

void *memcpy( void *dest, const void *src, size_t count );

这是对于memcpy函数的介绍。可以看到它的函数参数有三个:

一个是void*的目标地址

一个是const void*的源头地址。这里加const的目的是为了保障安全性

还有一个size_t类型的计数器,这里操作的个数单位是字节

并且返回值是void*的

演示:

可以观察到处于arr1位置开始的20个字节拷贝了从arr+5开始的20个字节所办含的内容。

分析:

其实前面讲的qsort函数的函数参数就是void*的参数,主要是对逐个字节进行操作。

那有了这个想法,我们就可以讲这两个指针后面20个字节的内容逐字节进行拷贝即可。

代码实现:

void my_memcpy(void* dest, void* src, int num)
{
	while (num)
	{
		*((char*)dest) = *((char*)src);
		src = (char*)src + 1;
		dest = (char*)dest + 1;
		num--;
	}
}

这里采用while循环,每操作一个字节就使num减少1。完成模拟。

运行演示:

 可以发现我们自己实现的这个memcpy函数可以模拟实现刚才库函数的效果。

二、memmove函数

memmove
Moves one buffer to another.

void *memmove( void *dest, const void *src, size_t count );

可以观察到。memmove函数也是void* 的返回值类型,同时也包含三个参数

那已经有memcpy函数了,为什么还会有memmove函数呢?其实,对于上面的代码。是内存不重叠部分进行的拷贝,如果我们需要拷贝的内存相互重叠了,依然采用我们上述的代码就会发生下面情况:

 内存并没有按照我们设想的那样进行复制。

我们理想情况下的:1 2 1 2 3 4 7 8 9 10

实际上是              :1 2 1 2 1 2 7 8 9 10

造成这种结果的原因其实就是我们在arr1[2]位置处拷贝了arr1[0]的数据后

arr1[2]中的结果已经被改为1了,所以下一次访问到它的时候,依然得到的是1

arr1[3]同理。

那怎样能够解决这个问题呢,C语言就设计了memmove函数;

演示:

 不难观察到:memmove函数可以完成这种重叠内存的拷贝。

那它是怎么实现的呢。

分析:

 这是我们的目标地址在源地址的后面的情况。当然还会有目标地址在前面的情况:

 那代码当然就需要分两个部分写了

先判断目标位置和原位置的前后关系,再分两步进行数据的复制:

代码:

void my_memmove(void* dest, void* src, int num)
{
	if (dest > src)
	{
		//后向前
		while (num)
		{
			*((char*)dest + num) = *((char*)src + num);
			num--;
		}
		*((char*)dest) = *((char*)src);
	}
	else
	{
		//从前向后
		while (num)
		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
			num--;
		}
	}
}

在从后向前进行复制的代码中:

只需要每次都找到对应的位置,循环操作相应的字节数即可

在从前向后进行复制的代码中:

dest和src指向下一个字节的代码要注意不可以直接++。

演示:

 总结:

其实现在vs自带的memcpy函数也不会出现诸如刚才复制错误的情况。但是我们自己写的函数就会错误。这其实是它后来优化的结果。尝试自己模拟实现库函数可以增强对指针和内存的理解。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/784636.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号