memcpy与memmove的区别

二者的函数原型:

void * memcpy ( void * destination, const void * source, size_t num );
void * memmove ( void * destination, const void * source, size_t num );

该两个函数都包含于string.h头文件中

destination即目标空间,即要复制到哪个空间
source即源空间,即要被复制的内存空间
num即要复制多少个字节的内容到destination
void*即返回目标空间

从函数原型上看,二者只有函数名称的区别,它们本质的区别在于它们的功能不同

  • 函数memcpy是用于从source的位置开始向后复制num个字节的数据到destination所在的内存位置(这个函数在遇到 '\0' 的时候并不会停下来)
  • 如果source和destination有任何的重叠,复制的结果都是未定义的

由于目标空间和源空间存在重叠,则无法按照预期逻辑进行赋值,故此后面设计出了memmove

  • 函数memmove和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理

如何模拟实现memcpy和memmove呢?

memcpy首先将void*强制转换成char*进行每一个字节的拷贝(str1和str2不重叠),然后指向目标空间和源空间地址的指针每次往后走一个字节的位置。循环拷贝相应的字节数即可。

代码实现如下

void* my_memcpy(void* dest, const void* src, size_t count) {
	assert(dest && src);
	void* ret = dest;

	while (count--) {
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

memmove则相对复杂一些,主要是考虑目标空间与源空间重叠的情况。

当目标空间指针(destination)地址小于源空间指针(source)地址时,则需要从源空间地址的末位开始从后向前拷贝;当目标空间指针地址大于源空间指针地址时,则从源空间开始从前向后拷贝。然后也是循环拷贝相应的字节数即可。

代码实现如下

void* my_memmove(void* dest, const void* src, size_t count) {
	assert(dest && src);
	void* ret = dest;
	if (dest < src) {
		while (count--) {
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else {
		dest = (char*)dest + count - 1;
		src = (char*)src + count - 1;
		while (count--) {
			*(char*)dest = *(char*)src;
			dest = (char*)dest - 1;
			src = (char*)src - 1;
		}
	}
	return ret;
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

c.Coder

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

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

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

打赏作者

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

抵扣说明:

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

余额充值