一些关于memcpy memmove函数的区别,和模拟实现
memcpy
它是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
函数原型:void* memcpy(void * dest, const void * src,size_t count)
1 #include<stdio.h
2 #include<assert.h>
3 void * memcpy (void * dst, const void * src, size_t count) { 4 assert(dst); 5 assert(src); 6 void * ret = dst; 7 char* pdst=(char*)dst; 8 char* psrc=(char*)src; 9 while (count--) { 10 *pdst++ = *psrc++; 11 } 12 return ret; 13 } 14 int main(){ 15 char str[] = "abcdefg"; 16 //char str0[] = "abcdefg"; 17 char str1[10]="abcdg"; 18 memcpy(str + 2, str, 4); 20 printf("以memcpy方式拷贝:%s\n", str + 2); 21 printf("期待的结果:%s\n", str1); 22 return 0; 23 }
如上,发现dst和src所指向的区域是有重叠的,这里其实就是吧str数组中前4个字符的“abcd”拷贝到str数组后“cdefg”字符中,
当赋值到第3个元素时发现 原来的‘c’,已被覆盖了,同理‘d’也是 最后导致成了“ababg”这样的结果。
注意: source和destin所指的内存区域可能重叠,但是如果source和destin所指的内存区域重叠,那么这个函数并不能够确保source所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。
memmove
该函数函数返回的是指向destin的指针,实现基本和memcpy类似。在处理区域重叠部分,它的原理是这样:
假设要把一字符数组src中的“ABCDEFG”赋值给字符数组dst中,它们都有重叠区域,那么就
分 和这两种情况来处理。
接下来实现memmove :
1 #include<stdio.h> 2 #include<assert.h> 3 void * memmove ( void * dst, const void * src, size_t count) { //将src内容拷贝count个字节到dst中,若拷贝过程中 4 assert(dst); //它们有重叠区域 ,用以上两种方式分别进行拷贝。规避了memcpy的缺陷 assert(src); 5 void * ret = dst; 6 char* pdst=(char*)dst; 7 const char* psrc=(const char*)src; 8 if (pdst > psrc && pdst < (psrc + count)) { //从后往前拷贝 9 while (count--) { 10 *(pdst+count )= *(psrc+count); 11 } 12 } 13 else { 14 while(count--){ 15 *pdst++=*psrc++; 16 } 17 } 18 return ret; 19 } 20 int main(){ 21 char str[] = "abcdefg"; 22 char str1[] = "abcdg"; 23 memmove(str + 2, str, 4); 24 printf("以memmove方式拷贝:\n"); 25 printf("内存覆盖情况下:%s\n", str + 2); 26 printf("期待情况:%s\n", str1); 27 return 0; 28 }以此,就可以在解决memcpy函数的缺陷了。
本文来自博客园,作者:tp_16b,转载请注明原文链接:https://www.cnblogs.com/tp-16b/p/7875797.html