目录
memcpy——内存拷贝
memcpy - C++ Reference (cplusplus.com)
memory——计算机里是内存的意思
copy ——复制
结合起来就是内存拷贝
参数
void* memcpy(char* destination, const char* source, size_t num);
char* destination 目的地,就是要拷贝到哪——给个首地址
char* source 源,从哪拷贝 ——也是首地址
size_t num 要拷贝的字节数 ——是字节数,不是个数
用法
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
memcpy(arr2, arr1, 20);//这里要拷贝1,2,3,4,5,共20字节
return 0;
}
//结果就是arr2[20] = { 1,2,3,4,5 };
工作原理
因为传的两个参数是 void* 的,作为库函数的实现者,他是不知道使用的人到底传什么参数,所以用void* 来接收两个首地址,不知道你要拷贝整形,结构体还是别的,所以就用字节个数作为拷贝长度。那么问题来了,用void* 和字节个数有什么用呢,下面我简单模拟实现一下库函数
void* my_memcpy(void* destination, const void* source, size_t num)
{
assert(destination && source); //断言,检查源和目的是不是空指针
char* p1 = (char*)destination; //强制类型转换,转换成char*之后,就可以不用管你是什么类型的
char* p2 = (char*)source; //变量,都按一个字节算,拷贝的时候一个字节一个字节的拷贝
while (num--)
{
*p1++ = *p2++; //memcpy是从源首地址的第一个字节拷贝到
//目的地址的首地址的第一个字节开始拷贝到最后一个
}
return destination;
memmove——内存移动(其实和内存拷贝意思一样)
memmove - C++ Reference (cplusplus.com)
参数
和memcpy的一样
用法
和memcpy的一样,那么问题来了,这两个是一样的吗?
不一样
工作原理
void* my_memmove(void* destination, const void* source, size_t num)
{
assert(destination && source);
char* p1 = (char*)destination;
char* p2 = (char*)source;
while (num--)
{
*(p1 + num - 1) = *(p2 + num - 1); //从源地址的最后一个字节开始拷贝,
} //拷贝到目的地最后一个字节
//从最后一个字节开始拷贝到第一个字节
return destination;
}
区别
注意事项
我们知道了memcpy和memmove 的具体实现原理,没有内存重叠的时候都是一样的用法,要是拷贝的内存有重叠的地方就有可能出现问题,那么具体是用memcpy还是memmove,可以画一个我给出的那种图,一目了然