memcpy和memmove

memcpy

功能:内存拷贝函数,从数据源拷贝num个字节的数据到目标数组

函数原型:

void * memcpy ( void * destination, const void * source, size_t num );

函数参数:

destination:指向目标数组的指针

source:指向数据源的指针

num:要拷贝的字节数

使用方法:

#include<stdio.h>
#include<string.h>
struct person
{
	char* name;
	char* sex;
};
int main()
{
	//使用memcpy拷贝字符串
	char* source = "there have something"; 
	char desc[50];
	std::memcpy(desc,source,strlen(source)+1); //不能用sizeof,sizeof(str2)指的是指针的大小
	std::cout<<"dec[]="<<desc<<std::endl;

        //拷贝字符串中的某些字符
        char* s1 = "nothing is impossible";
        char s2[40];
        std::memcpy(s2,s1+10,strlen(s1)+1-10);
        std::cout<<"s2: "<<s2<<std::endl;

        //使用memcpy拷贝字符数组
	char str1[] = "made in china";
	char str2[50];
	std::memcpy(str2,str1,sizeof(str1)); //或者strlen(str1)+1
	std::cout<<"str2: "<<str2<<std::endl;

	//使用memcpy拷贝结构体
	person p;
	person p2;
	p.name = "Qiana";
	p.sex = "女";
	std::memcpy(&p2,&p,sizeof(person));
	std::cout<<"p2.name: "<<p2.name<<std::endl;
	std::cout<<"p2.sex: "<<p2.sex<<std::endl;

	return 0;
}

注意:destination是指向目标数组的指针,数组名做参数,传的是数组首元素的首地址。当传的是一个指针的时候,就会出错,指针未初始化的时候,指向一个未知的区域,里面有随机值,且不知道大小和数据类型,当源数据对它进行赋值的时候,会出错所以memcpy的第一个参数,传一个大小大于源数据的数组。

	char* s1 = "nothing is impossible";
	char* s2;
	std::memcpy(s2,s1+10,strlen(s1)+1-10);
        //这样是不对的

模拟实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>

void* mymemcpy(void* desc,const void* src,size_t size)
{
	void* ret = desc;
	char* str1 = (char*)desc;
	char* str2 = (char*)src;
	assert(str1);
	assert(str2);
	while(size--)
	{
		*str1++ = *str2++;
	}
	return ret;
}

int main()
{
	char s1[] = "hello world";
	char s2[20];
	int a1[] = {1,2,3,4,5,6,7,8,9};
	int a2[10];
	mymemcpy(s2,s1,sizeof(s1));
	std::cout<<s2<<std::endl;
	mymemcpy(a2,a1,sizeof(a1));
	int size = sizeof(a1)/sizeof(a1[0]);
	for(int i = 0;i < size;++i)
	{
		std::cout<<a2[i]<<" ";
	}
	std::cout<<std::endl;
	return 0;
}

memmove

功能:内存移动函数,从source所指向的对象复制num个到destination所指向的对象,允许内存重叠。

函数原型:

void * memmove ( void * destination, const void * source, size_t num );

内存重叠:例如,char s1[] = "123456789" ,复制“3456”到“5678”,“56”是重叠部分,若用memcpy拷贝,将“34”拷贝到了“56”的位置,导致将“56”拷贝到“78”时,“56”已经不存在了,被“34”覆盖了。而memmove就是解决memcpy不能内存重叠的问题,比memcpy更加的安全。如果目标区域和源区域没有重叠,则memmove和memcpy的函数作用相同。

函数参数:

destination:指向目标数组的指针

source:指向数据源的指针

num:要拷贝的字节数

使用方法:

#include<stdio.h>
#include<string.h>

int main()
{
	char str1[32] = "juice in the July"; 
	char str2[32] = "hello world";
	
	//使用memmove拷贝到另一个数组中,同memcpy
	memmove(str2,str1,sizeof(str1));
	std::cout<<"str2:"<<str2<<std::endl;

	memmove(str2,"begin\0end",sizeof(str2)); //\0是字符串的结束标志
	std::cout<<"str2:"<<str2<<std::endl;

	//在一个数组中进行拷贝
	memmove(str1+13,str1+6,2);
	puts(str1);

	//进行内存重叠的拷贝
	char str3[] = "123456789";
	memmove(str3+4,str3+2,4);
	std::cout<<"str3:"<<str3<<std::endl;

	return 0;
}

模拟实现:

void* my_memmove(void* desc,const void* src,size_t num)
{
	void* ret = desc;
	char* str1 = (char*)desc;
	char* str2 = (char*)src;
	assert(str1);
	assert(str2);
	if(str1 > str2)
	{
		while(num--)  //循环num次,由num=num-1到num=0
		{
			*(str1+num) = *(str2+num);
		}
	}
	else
	{
		while(num--)
		{
			*str1++ = *str2++;
		}
	}

	return ret;
}

int main()
{
	char s1[] = "123456789";
	char s2[] = "234567123456";
	my_memmove(s1+4,s1+2,4);
	std::cout<<"s1: "<<s1<<std::endl;

	my_memmove(s1,s1+5,4);
	std::cout<<"s1: "<<s1<<std::endl;

	my_memmove(s2,s1,sizeof(s1));
	std::cout<<"s2: "<<s2<<std::endl;

	return 0;
}


memcpy与memmove的区别:

memcpy是内存拷贝函数,memmove是内存移动函数,两个函数的作用差不多,区别在于memmove允许内存重叠,也就是允许反向拷贝。memmove比memcpy更安全一些。

O(∩_∩)O!


猜你喜欢

转载自blog.csdn.net/qiana_/article/details/79951106