前面已经介绍了str类的函数,那么在这边将为大家介绍一下mem类的内存拷贝函数的相关使用。
memcpy的使用
首先看一下memcpy在cplusplus.com(点击直达该网站进行搜索)上的使用。
可以看到,该函数的返回值是void*。其中他的三个参数中,第一个是目的地的地址(想要复制到哪里),第二个表示原地址(想从什么地方开始复制),第三个是大小(表示想要复制几个字节,注意是字节的大小)。
下面是代码演示。
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };//原空间
int arr2[10] = { 0 };//目的地空间
memcpy(arr2, arr1, sizeof(arr1[0]) * 10);//进行拷贝操作
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
可以看到,数据被成功从arr1拷贝到arr2。
memmove的使用
同样有需要可以在cplusplus.com上搜索进行使用。
可以看到这个函数的参数和返回类型和memcpy一模一样。
下面是代码演示。
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, sizeof(arr1[0]) * 10);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
同样的,他也能得到将arr1的内容拷贝到arr2的作用。
那为什么要设置两个相同功能的函数呢?
下面就来演示下两个函数的区别
题目:将数组1中的整个元素向后移动一个单位长度
memcpy代码演示:
int arr1[11] = { 1,2,3,4,5,6,7,8,9,10 };
memcpy(arr1+1, arr1, sizeof(arr1[0]) * 10);//将整个数组元素向后移一个单位长度
int i = 0;
for (i = 0; i < 11; i++)
{
printf("%d ", arr1[i]);
}
memmove代码演示:
int arr1[11] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1+1, arr1, sizeof(arr1[0]) * 10);
int i = 0;
for (i = 0; i < 11; i++)
{
printf("%d ", arr1[i]);
}
可以发现,当有内存重叠的部分进行拷贝时,memmove能达到效果,但是memcpy却不行。这是因为memcpy是逐字节进行拷贝,当原地址与目标地址相同时就会发生冲突,导致达不到想要的效果。
而memmove是将数据从要拷贝的内存区域复制到一个临时缓冲区中,然后再从缓冲区中把数据拷贝到目标地址中去,因此可以保证即使源地址和目标地址重叠,也能够正确地完成数据的拷贝,不会出现数据的错误或丢失。
但是相对于memcpy函数,memmove函数会稍微慢一些,因为需要额外的缓冲区。
关于以上两个函数在VS、Dev以及其他编译器上的疑问
那么这边就有小伙伴进行两函数的实践时就会发现memcpy也能达到内存重叠时的拷贝效果啊,和memmove的效果一样啊等等这样的疑问。
在这边就有必要进行说明,在IDE中确实是这样的。不过这只是代码在当前编译器下的认为你想要的效果是如此才会让代码达到这样的效果。但这并不是一个良好的习惯,根据C语言标准来说是不准确的。因为程序员们将来所写的代码会运用到各种环境下,在不同的编译器,不同的操作系统环境中,代码的执行标准是根据他的语言对应的标准来说的。所以如果只是单纯将memcpy也用到内存重叠的拷贝中,那么程序的运行结果是不可预测的。
因此应该尽量避免使用memcpy函数处理重叠内存,而是使用memmove函数来确保数据拷贝的正确性和稳定性。
如有问题,请评论留言~~