1.模拟实现memcpy
memcpy函数原型:
void * memcpy(void *dest, const void *src, size_t len);
作用及注意点:
1.函数从src位置开始向后复制len长度个字节的数据到dest的内存上。
2.遇到'\0'时不会停下。
3.memcpy可以拷贝任何类型的数据。
模拟分析:
1.因为我们无法知道函数拷贝的数据类型,无法知道传到memcpy函数的地址的类型,故传过来的地址用void*类型的指针接受
2.为了保护源地址处储存的地址,用const void*类型的指针来接收。
3.由于dest在拷贝时会改变存储内容,为了返回拷贝后的目标的起始地址,所以我们要事先创建一个void*类型的地址来存储这个地址。
4.为了避免传入空指针,我们借用assert函数来判断,头文件使用"assert.h"。
模拟实现代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t sz)
{
assert(dest && src);
void* ret = dest;
while (sz--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int a1[10] = { 0 };
int a2[] = { 1,2,3,4,5 };
my_memcpy(a1, a2, 20);//此处的sz为拷贝的字节大小。
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d", a1[i]);
}
return 0;
}
运行结果:
2.模拟实现memmove
memmove函数原型:
void * memmove ( void * dest, const void * src, size_t sz );
作用:
进行重叠内存的拷贝。
模拟分析:
1.在进行memmove函数拷贝时,有两种情况需要注意:
情况一:dest地址小于src的地址时。
1 2 3 4 5 6 7 8 9 10
当dest的地址在 1 前,src的地址在2和3之间时,必须从前往后拷贝才不会重叠。
情况二:dest地址大于src的地址时。
1 2 3 4 5 6 7 8 9 10
当dest的地址在4和5之间,src的地址在1和2之间时,必须从后往前拷贝才不会重叠。
模拟实现代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t sz)
{
assert(dest && src);
void* ret = dest;
if (dest < src)
{
int i = 0;
for (i = 0; i < sz; i++)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
while (sz--)
{
*((char*)dest + sz) = *((char*)src + sz);
}
}
return ret;
}
int main()
{
int a1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(a1, a1 + 2, 20);
for (int i = 0; i < 10; i++)
{
printf("%d", a1[i]);
}
}
运行结果:
总结:
以上便是memcpy和memmove两个函数的模拟实现,初次创作如有错误欢迎提供建议,如果喜欢,感谢关注支持!