memcpy 函数、 memmove函数用法及模拟实现

一、memcpy 内存拷贝函数

函数描述:void * memcpy ( void * destination, const void * source, size_t num )
功能: 从存储区 source复制 n 个字符到存储区 destination。
参数

  • destination-- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
  • source-- 指向要复制的数据源,类型强制转换为 void* 指针。
  • num – 要被复制的字节数。

返回值:
该函数返回一个指向目标存储区 destination的指针。
注意:

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 ‘\0’ 的时候并不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的。
    使用示例:
#include<stdio.h>
#include<string.h>

struct{
	char name[40];
	int age;
	
}person,person_copy;

int main()
{
	char myname[]="Poerre de Fermat";
	
	//用memcpy拷贝字符串举例
	memcpy(person.name,myname,strlen(myname)+1);
	person.age= 46;
	
	//用memcpy拷贝结构体
	memcpy(&person_copy,&person,sizeof(person));
	
	printf("person_copy: %s,%d\n",person_copy.name,person_copy.age);
	return 0; 
 }

结果:
在这里插入图片描述
memcpy的模拟实现:
代码如下:

void* my_memcpy(void* desc,void* src,size_t count)
{
	void* ret=desc;
	while(count--)
	{
		*(char*)desc=*(char*)src;
		desc=(char*) desc+1;
		src=(char*) src+1;
	}
	
	return ret;
 }

二、memmove函数

函数描述:void * memmove ( void * destination, const void * source, size_t num );
**功能:**由src所指内存区域复制count个字节到dest所指内存区域。
说明:

返回值:返回指向destination的指针

  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理
int main()
{
	char str[]="memmove can be very useful......";
	memmove(str+20,str+15,11);
	puts(str);
 } 

结果:
在这里插入图片描述
memmove的模拟实现:
分析:

int arr[6] = {1,2,3,4,5,6}; 
将数组前4个元素复制到后4个元素上,即将数组变为 
{1,2,1,2,3,4} 
将数组还原为初始在将后四个元素复制到三个元素上,即为 
{3,4,3,4,5,6}

直接使用memcpy函数:
实际运行结果:121212
期待结果:121234

  • 拷贝目标和源有重叠部分!
  • 我们将前两个元素拷贝后3,4就变成了1,2,这样3,4就丢失了,在拷贝三和四的位置时实际拷贝的又是1,2。
  • 我们想到一个解决方法就是倒着拷贝,这样就不会丢失3,4。但是倒着拷贝如果想实现题目中的第二种境况时又会发生丢失。
  • 也就是说,既有需要从前向后拷贝的情况也有从后向前拷贝的情况。

模拟代码如下:

 void * my_memmove ( void * dst, const void * src, size_t count) 
 {
 	void* ret=dst;
 	//不存在覆盖的情况下,直接进行拷贝 
	 if(dst<=src||((char*)dst>=(char*)src+count))
	 {
	 	while(count--)
		 {
		 	*(char*) dst=*(char*) src;
		 	dst=(char*) dst+1;
		 	src=(char*) src+1;
		  } 
	  } 
	  //存在覆盖,逆向拷贝。 
	  else
	  {
	  	dst=(char*) dst+count-1;
		src=(char*) src+count-1;
		while(count--)
		{
			*(char*) dst= *(char*) src;
			dst=(char*) dst-1;
			src=(char*) src-1;
		}
	  }
	  return ret;
 }
发布了70 篇原创文章 · 获赞 12 · 访问量 9800

猜你喜欢

转载自blog.csdn.net/lovehang99/article/details/100540070