模拟实现memcpy和memmove

1.memcpy

先上代码

#include
#include
#include
void* my_memcpy(void* dest, const void* src, size_t num)//num - 字节
{
	void* ret = dest;
	assert(dest && src);
	while (num--)
	{
		*(char*)dest = *(char*)src;//拷贝一个字节
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//1 2 3 4 5拷贝到 3 4 5 6 7
	//1 2 1 2 3 4 5 8 9 10
	my_memcpy(arr + 2, arr, 5 * sizeof(arr[0]));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

C语言中只要求memcpy能拷贝不重叠的内存空间就可以了,所以不用管重叠问题,直接拷贝想要的内存就可以了

首先,需要三个参数 -- 最后传递到的地址,起始传递的地址以及传递的大小

先判断两个指针是否为野指针

然后将void*强转为char*

这样可以一个字节一个字节的拷贝

然后每拷贝一次就让dest和src各自+1

这样确保每个字节都会被拷贝

一共循环num次

最后return到一开始dest的位置

2.memmove

void* my_memove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	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);
		}
	}
}

由于memmove需要考虑内存重叠问题,所以需要考虑两种情况

什么是内存重叠问题?

比如有一个数组 int arr[] = { 1,2,3,4,5,6,7,8,9,10 };

我们想要把1 2 3 4 5拷贝到 3 4 5 6 7
最终得到1 2 1 2 3 4 5 8 9 10

如果使用my_memcpy的话最终会得到1 2 1 2 1 2 1 8 9 10

这是为什么呢?

因为数组下标从arr[0] 到 arr[9]

我们想把arr[0]到arr[4]拷贝到arr[2]到arr[6]

当我们拷贝完arr[0]和arr[1]之后 数组已经变成1 2 1 2 5 6 7 8 9 10

当我们要把arr[2]拷贝到arr[4]时arr[2]现在已经变成了1而不是3 

所以使用memcpy的话会得到1 2 1 2这样的结果

所以我们要考虑两种情况应对内存重叠问题

如果dest

比如如果要把1 2 3 4 5拷贝到 3 4 5 6 7

就 1 2 3 4 5的拷贝

如果dest>src,就把要拷贝的数据从后向前拷贝

比如如果要把1 2 3 4 5拷贝到 3 4 5 6 7

就 5 4 3 2 1的拷贝

比如:

1 2 3 4 5 6 7 8 9 10

1 2 3 4 5 6 5 8 9 10

1 2 3 4 5 4 5 8 9 10

1 2 3 4 3 4 5 8 9 10

1 2 3 2 3 4 5 8 9 10

最终得到

1 2 1 2 3 4 5 8 9 10

你可能感兴趣的:(c语言)