memcpy 和memmove 都是把一个内存块拷贝到另一个内存块,其区别为:
memcpy 不考虑源内存块和 目标内存块 是否重叠的情况,即
source | |
dest | |
而memmove则考虑了这一情况,当遇到这种情况的时候,拷贝是从最高位开始,这样就保证source中还没拷贝的块不会因为dest的原因被修改。
#include <stdio.h> #include <stdlib.h> #include <assert.h> /** *mymemcpy 把source 复制到dest, 返回dest的头指针, count 是指针长度 **/ void * mymemcpy(void * dest, const void * source, size_t count) { assert(dest != NULL || source != NULL); void * ret = dest; //记录dest初始地址 while(count--) { *(char *)dest = *(char *)source; //*dest = *source; void * 只知道所指内容的起始地址,不知道所指内容的大小(占几个字节),所以无法正确引用 dest = (char *)dest + 1; source =(char *)source + 1; } return ret; } /** * memcpy 没有考虑当source 和dest 有以下内存地址重叠的情况: * source | | * dest| | * 即source向dest复制的时候,会改变source后面需要复制的内容。 * 解决办法,当这种情况出现时,可以考虑从最高位向最低位复制。 **/ void * mymemmove(void * dest, const void * source, size_t count) { assert(dest != NULL || source != NULL); void * ret = dest; if(dest < source || dest > (char *) source + count -1) //不会出现重叠情况 { while(count--) { *(char *) dest = * (char *) source; dest = (char *)dest + 1; source = (char *)source + 1; } } else { while(count--) { *((char *) dest + count) = *((char *) source + count ); } } return ret; } int main() { char a[] = "abcdefgh"; //mymemcpy(a+2, a, 4); mymemmove(a+2, a, 4); printf("%s\n",a); return 0; }