使用memmove并模拟实现

1、memcpy函数

1.1memcpy函数的基本介绍

要讨论memmove,那memcpy自然是不能忽略的,这两个函数的功能非常相似,或者说memmove是memcpy的升级版本。我们打开MSDN可以看到这个函数的的头文件是memory.h或是string.h。参数分别是目标地址,源地址和需要拷贝的长度,返回类型是void*。

 

这个函数的作用我们也可以看出这个函数的作用和strcpy很相似,不同的是strcpy只能拷贝字符串。而memcpy是可以拷贝任何类型的数据的。

1.2、memcpy的缺点

但是这个函数也有一些问题。比如我想要拷贝的的目标地址和源地址是一个同一个数组,而且有重叠的情况下就会发生内容覆盖。就像这样。

我想把34567的内容拷贝到现在的56789的位置,因为56的位置已经被覆盖成了34,那么我们在使用memcpy就会导致这样的情况。

 

所以就有了memmove这个函数的出现。

2、memmove 函数

2.1、memmove函数的基本介绍

我们再来看看MSDN对于memmove这个函数的解释

 

 

 

 memmove实现的功能跟memcpy一样但是不同的是memmove解决了前面说的问题。那我要怎么去实现这个函数呢?

3、memcpy函数的模拟实现 

我们 要实现memcpy只要将每个字节的内容拷贝到目标位置就行所以说可以借助for循环和强制转换为(char*)类型的指针(由于char*类型的指针解引用的访问权限是一个字节)。

void* my_memcpy(const void* src, void* dst, size_t len)
{
	assert(src && dst);
	int* ret = dst;
	for (int i = 0; i < len; i++)
	{
		*(char*)dst = *(char*)src;
		((char*)dst)++;
		((char*)src)++;
	}
	return ret;
}

由于src源地址的内容是不需要改变的所以说我们可以加上const保护。

再加上assert进行断言防止函数使用时传入空指针 

 非常的容易。

4、memmove函数的模拟实现

 

 还是这个数据,我们要怎么去解决覆盖问题呢?我们可以从后往前拷贝也就是

7->9   6->8   5->7   4->6   3->5

这样就可以解决这个问题,但是如果目标空间在源空间的前面呢?如果还是使用从后往前拷贝的方法,就会把前面的内容覆盖了。就像这样

那么我们可以进行分类讨论,也就是借助if条件语句。

 

我们发现这是一个分界点,

如果dst在src的前面那就使用从前向后拷贝的方法

如果dst在src的后面那就使用从后向前拷贝的方法 

 我们就可以用dst-src去判断前后关系,但是由于我们的dst和src都是无类型的指针,所以说要先进行强制类型转换,在进行运算。

所以我们就可以写出下面的部分

如果dst在src的前面,也就是 (char*)dst - (char*)src < 0 ,那就使用从前向后拷贝的方法

如果dst在src的后面,也就是 (char*)dst - (char*)src > 0 ,那就使用从后向前拷贝的方法 

 

void* my_memmove(void* dst, const void* src, size_t len)
{
	    int ret = dst;
		if ((char*)dst - (char*)src < 0)
		{
			for (int i = 0; i < len; i++)
			{
				(char*)dst = *(char*)src;
				((char*)src)++;
				((char*)dst)++;
			}
		}
		else
		{
			for (int i = len - 1; i >= 0; i--)
			{
				*((char*)dst + i) = *((char*)src + i);
			}
		}
		return ret;
}

memmove就可以很好地实现出来了 

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

东莞呵呵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值