区别很简单,看这两个函数的man手册就能看的出来。简单来说,memmove是把一堆byte从src移到dst,memcpy是把一堆byte从 src拷贝到dst,最大不同的是:memmove是先把一堆byte拷贝到一个临时的array中,然后再把这个临时的array写到dst中去;而 memcpy没有这个逻辑,直接就是从src一个一个字节的读,同时往dst一个一个字节的写。这样就导致了一个最根本的不同:
memcpy不适合或者说不能处理src和dst两块内存有重叠(overlap)的情况。因为memcpy是直接从src拷贝,然后往dst中写,这样,如果src和dst两块内存有重叠,这样就会导致写数据出错了。比如:
这样的情况,由于dst和src有重叠的部分,这样,在写dst的时候,同时就把src中的内容也改写了,这样拷贝出来的东西就不对了。
这就是两者的区别。下面给出一段代码来更明确的显式这两个函数的用法。代码来自lftp的源代码,我也是看了这段源代码才知道这两个函数有这样大的区别的。
这段代码是一个复制s到mem中的function,s和mem都表示string,len是s这个string的长度。函数中的 xmalloc, xfree就相当于malloc和free,只不过做了一些封装,加了一个计数器进去用来追踪申请和释放的次数而已。关键的就是看这个函数中的几个if判 断,这些if判断就是判断mem和s两者有没有重叠的部分,从而调用不同的函数。
memcpy不适合或者说不能处理src和dst两块内存有重叠(overlap)的情况。因为memcpy是直接从src拷贝,然后往dst中写,这样,如果src和dst两块内存有重叠,这样就会导致写数据出错了。比如:
- Code: Select all
src.........\0
dst.........\0
这样的情况,由于dst和src有重叠的部分,这样,在写dst的时候,同时就把src中的内容也改写了,这样拷贝出来的东西就不对了。
这就是两者的区别。下面给出一段代码来更明确的显式这两个函数的用法。代码来自lftp的源代码,我也是看了这段源代码才知道这两个函数有这样大的区别的。
- Code: Select all
/*
* replace string mem by string s, len is the length of string s
* NOTE: use memmove while mem & s has overlaps and use
* memcpy while they have no overlaps
*/
char *xstrset(char *&mem,const char *s,size_t len)
{
if(!s)
{
xfree(mem);
return mem=0;
}
#ifdef MEM_DEBUG
printf("xstrset \"%.*s\"\n",len,s);
#endif
if(s==mem)
{
mem[len]=0;
return mem;
}
size_t old_len=(mem?strlen(mem)+1:0);
// s & mem have overlaps
// and s's start point is in mem's range
// so use memmove, cannot use memcpy
// mem.........\0
// s..............\0
// after memmove
// mem..............\0 -- mem has new contents(s)
if(mem && s>mem && s<mem+old_len)
{
memmove(mem,s,len);
mem[len]=0;
return mem;
}
// mem & s have no overlaps and the mem is too small
// mem cannot accommodate the whole `s' so realloc the memory
if(old_len<len+1)
mem=(char*)xrealloc(mem,len+1);
memcpy(mem,s,len);
mem[len]=0;
return mem;
}
这段代码是一个复制s到mem中的function,s和mem都表示string,len是s这个string的长度。函数中的 xmalloc, xfree就相当于malloc和free,只不过做了一些封装,加了一个计数器进去用来追踪申请和释放的次数而已。关键的就是看这个函数中的几个if判 断,这些if判断就是判断mem和s两者有没有重叠的部分,从而调用不同的函数。