一、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版权协议,转载请附上原文出处链接和本声明。