先上代码
#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的位置
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