C/C++总结笔记——关键字4: memcpy及其内存重叠、memmove

memcpy

C/C++ 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1。

#include 
#include
 
int main(){
	int d[10]={1,2,3,4,5,6,7,8,9,10};
	memcpy(d+3, d, 7*sizeof(int));// 注意第三函数为字节数
	for(int i=0;i<10;i++){
		printf("%d ", d[i]);
	}
	return 0;
}
/*输出
1 2 3 1 2 3 4 5 6 7
*/

从上面代码运行结果看不出什么问题来,其实隐含的问题(内存重叠)已经在现在的版本中被解决了。
接下来看看这个可能被HR问到的问题。

memcpy内存重叠

举个例子:数组a[10]={0,1,2,3,4,5,6,7,8,9},将a中的从下标0开始的7个数据,储存到从下标3开始的该数组中,我们想要的结果则为:a[10]={0 1 2 0 1 2 3 4 5 6}。但memcpy之前采用的算法为从下标0开始依次复制到从下标3的地址,结果为a[10]={0 1 2 0 1 2 0 1 2 0},如示例1代码运行结果。这是因为复制的内存存在着重叠现象。
在这里插入图片描述
示例1

#include 
#include
#include 

void *memcpy(void *dst, const void *src, size_t len)
{
	if(NULL == dst || NULL == src){
		return NULL;
	}
	
	void *ret = dst;

	while(len--){
		*(char *)dst = *(char *)src;
		dst = (char *)dst + 1;
		src = (char *)src + 1;
	}
	return ret;
}

int main(){

	int d[10]={0,1,2,3,4,5,6,7,8,9};
	memcpy(d+3, d, 7*sizeof(int));
	for(int i=0;i<10;i++){
		printf("%d ", d[i]);
	}
	return 0;
}
/*输出
1 2 3 1 2 3 1 2 3 1 
*/

内存重叠问题通过示例2进行解决,先判断是否发生内存重叠,再通过先复制重叠地址的内容再复制其他内容进行解决。

示例2

#include 
#include
#include 

void *memcpy(void *dst, const void *src, size_t len)
{
	if(NULL == dst || NULL == src){
		return NULL;
	}
	
	void *ret = dst;
	
	if(dst <= src || (char *)dst >= (char *)src + len){
		//没有内存重叠,从低地址开始复制
		while(len--){
			*(char *)dst = *(char *)src;
			dst = (char *)dst + 1;
			src = (char *)src + 1;
		}
	}else{
		//有内存重叠,从高地址开始复制
		src = (char *)src + len - 1;
		dst = (char *)dst + len - 1;
		while(len--){
			*(char *)dst = *(char *)src;
			dst = (char *)dst - 1;
			src = (char *)src - 1;
		}
	}
	return ret;
}

int main(){

	int d[10]={0,1,2,3,4,5,6,7,8,9};
	memcpy(d+3, d, 7*sizeof(int));
	for(int i=0;i<10;i++){
		printf("%d ", d[i]);
	}
	return 0;
}
/*输出
0 1 2 0 1 2 3 4 5 6
*/

示例2的实现其实就是memmove()的实现。memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。

https://www.runoob.com/cprogramming/c-function-memcpy.html
https://blog.csdn.net/lz20120808/article/details/52135046
https://blog.csdn.net/lxgwm2008/article/details/11952285

你可能感兴趣的:(c语言,c++,开发语言)