memcpy和memmove()都是C语言中的库函数,在头文件string.h中,做用是拷贝必定长度的内存的内容,原型分别以下:
void *memcpy(void *dst, const void *src, size_t count);
void *memmove(void *dst, const void *src, size_t count);
他们的做用是同样的,惟一的区别是,当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。
第一种状况下,拷贝重叠的区域不会出现问题,内容都可以正确的被拷贝。
第二种状况下,问题出如今右边的两个字节,这两个字节的原来的内容首先就被覆盖了,并且没有保存。因此接下来拷贝的时候,拷贝的是已经被覆盖的内容,显然这是有问题的。
实际上,memcpy只是memmove的一个子集。
两者的c语言实现很简单,有兴趣的朋友能够去看看。在实际状况下,这两个函数都是用汇编实现的。
memmove在copy两个有重叠区域的内存时能够保证copy的正确,而memcopy就不行了,但memcopy比memmove的速度要快一些,如:
char s[] = "1234567890";
char* p1 = s;
char* p2 = s+2;
memcpy(p2, p1, 5)与memmove(p2, p1, 5)的结果就多是不一样的,memmove()能够将p1的头5个字符"12345"正确拷贝至p2,而memcpy()的结果就不必定正确了
memcpy()、 memmove()和memccpy()
-------------------------------------------------------
这三个函数的功能均是将某个内存块复制到另外一个内存块。前两个函数的区别在于它们处理内存区域重叠(overlapping)的方式不一样。第三个函数的功能也是复制内存,可是若是遇到某个特定值时当即中止复制。
对于库函数来讲,因为没有办法知道传递给他的内存区域的状况,因此应该使用memmove()函数。经过这个函数,能够保证不会出现任何内存块重叠问题。而对于应用程序来讲,由于代码“知道”两个内存块不会重叠,因此能够安全地使用memcpy()函数。
原型:extern void *memccpy(void *dest, void *src, unsigned char ch, unsigned int count);
用法:#include
功能:由src所指内存区域复制很少于count个字节到dest所指内存区域,若是遇到字符ch则中止复制。
说明:返回指向字符ch后的第一个字符的指针,若是src前n个字节中不存在ch则返回NULL。ch被复制。
char s[]="Goldenx Global View";
char d[20];
char *p;
p=(char *)memccpy(d,s,'x',strlen(s));
if(p)
{
*p='\0'; // MUST Do This
printf("Char found: %s.\n",d);
}
else
printf("Char not found.\n");
关于memmove的实现:安全
点击(此处)折叠或打开app
关于memcpy的实现:函数
点击(此处)折叠或打开spa
############################################################################.net
memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。unix
但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增长了一点点开销。指针
memmove的处理措施:code
(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝blog
(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝内存
(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝
-- memcpy实现
1 2 3 4 5 6 7 8 |
|
-- memmove实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
示意图:
(1)内存低端 <-----s-----> <-----d-----> 内存高端 start at end of s (2)内存低端 <-----s--<==>--d-----> 内存高端 start at end of s (3)内存低端 <-----sd-----> 内存高端 do nothing (4)内存低端 <-----d--<==>--s-----> 内存高端 start at beginning of s (5)内存低端 <-----d-----> <-----s-----> 内存高端 start at beginning of s