引言:
上篇博客我们说到,在memcpy模拟实现使用时,对于重复的内存,我们会达不到预期的效果,所以,C语言给我们提供了内存重复进行拷贝的内存函数,memmove。
memmove函数使用:
memcpy和memmove的区别就是memmove是处理函数源头内存和目标内存重叠的情况。
例如下列代码所示:
#include<stdio.h>
#include<string.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
memmove(arr + 2, arr, 20);
int i = 0;
for (i = 0;i < 10;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
可以看到,我们的memmove完美的完成了我们对重复内存的拷贝实现。
那么,memmove是怎样对我们的内存进行管理和拷贝的呢,下面我们就来对memmove这个函数进行模拟实现。
memmove函数模拟实现:
我们先将memmove函数的大体框架构建出来,可以看到它的传参和memcpy是基本一致的,所以我们对memmove函数的大体框架可以这样构造:
#include<stdio.h>
void my_memmove(void* dest, void* stu, size_t num)
{
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
my_memmove(arr+2, arr, 20);
return 0;
}
这个代码可以理解为:在arr+2的位置,也就是从3开始,向后拷贝arr中的20个字节的内容,也就是将1,2,3,4,5覆盖到3,4,5,6,7上,那么应该怎么来实现呢?我们来画图理解一下:
可以看到,我们的dest表示要拷贝的位置的首地址,stu表示要拷贝的内容的首地址,可以看到,当我们从前向后拷贝的时候,内容会被覆盖,那么我们可以换个方式,我们从后往前拷贝字节内容,是不是就可以完美的将stu中的内容拷贝到dest开始的位置呢?
那么我们要如何获取最后一个字节的地址呢? 其实很简单,只要将我们指向首地址的指针强制转换为char* 类型 向后加num个字节,每次拷贝完一份,我们让num减1,是不是就可以得到倒数第二个字节的地址信息呢?
那么可以设想,如果我们的stu不大于dest,是不是直接从前向后拷贝就可以呢,通过这个设想,我们来完成我们的代码实现:
#include<stdio.h>
void my_memmove(void* dest, void* stu, size_t num)
{
if (dest > stu)
{
while (num--)
{
*(((char*)dest) + num) = *(((char*)stu) + num);
}
}
else
{
while (num--)
{
*(char*)dest = *(char*)stu;
dest = (char*)dest + 1;
stu = (char*)stu + 1;
}
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
my_memmove(arr+2, arr, 20);
int i = 0;
for (i = 0;i < 10;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
如果我们的dest>stu,我们就从后往前拷贝,如果不大于或等于,就从前往后就可以了,
然后我们运行一下,就可以得到如下结果:
可以看到,我们自己模拟的这个mommove完美的完成了我们想要的效果,以上就是memmove的模拟实现。
感谢大家的观看,喜欢内容的话可以点赞关注+收藏哦,感谢观看!