【C语言】memmove函数和memcpy函数的模拟实现

一、memcpy函数的模拟实现

 memcpy函数的功能是从source的开始位置拷贝num个字节的数据到destination。如果destination存在数据,将会被覆盖。memcpy函数的返回值是destination的指针。memcpy函数定义在string.h头文件里。

其中void*类型为泛型指针,因此可以接受任意类型的指针,所以memcpy可以实现任意类型的拷贝

使用示例:

输出结果为 :dbc

 模拟实现:

void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);//dest src 不能为空指针
	void* ret = dest;//最后要返回dest,但是下面dest会更改,因此这里先创建ret把dest存起来
	while (num--)
	{
		*(char*)dest = *(char*)src;//因为memcpy是一个字节一个字节拷贝,所以强制类型转换为char*
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	char arr1[] = "abc";
	char arr2[] = "def";
	void* ret = my_memcpy(arr1, arr2, 1);
	printf("%s", arr1);
	return 0;
}

 输出结果为:dbc

但是当我们要实现下面这种情况是时

当我们要把arr1数组中1,2,3,4,5拷贝到3,4,5,6,7上面

输出结果为1 2 1 2 1 2 18 9 10

 原因是当我们将1,2拷贝到3,4后,我们想要拷贝3,4到5,6处,但是原来的3,4的位置已经拷贝了1,2,所以继续把1,2拷贝到5,6处

 所以memcpy无法用来处理重叠内存之间的数据拷贝

但是memmove可以用来处理重叠内存之间的数据拷贝

二、memmove函数的模拟实现

 memmove函数的返回类型和参数与memcpy完全一致

 当我们要把1,2,3,4,5拷贝到3,4,5,6,7时

我们可以先把5拷贝到7,再把4拷贝到6,再把3拷贝到5,以此类推,这样就不会出现覆盖问题

 

 当我们要把3,4,5,6,7拷贝到1,2,3,4,5时

可以先前拷贝,先3→1,在4→2,在5→3,以此类推

代码实现:

void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)//判断向前拷贝还是向后拷贝
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}

	}
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1 + 2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

输出结果为:

 


版权声明:本文为m0_68991804原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。