memmove 与memcopy 的区别
内存重叠的概念
顾名思义,重叠就是有重复的部分。在字符串拷贝的过程中,还没被拷贝就已经被覆盖了原来的值。内存重叠在拷贝的过程中指源指针开始的内存与目的指针指的内存有重叠。我们可以在同一个数组中模拟内存重叠的现象。
内存重叠的现象
内存重叠只有在目的地址为pos1、pos2的时候才会存在。其中目的地址起始地址为pos1的情况下,只能从src起始位置拷贝。在目的地址为pos2的情况下,只能从src的end处开始拷贝,这样src原有的值会在覆盖前拷贝到目的地址。pos3的情况不会发生内存重叠的情况,也就是从src begin处或src end处开始拷贝字符串都OK。
我们首先看一下内存重叠的车祸现场,测试代码如下:
void testMemcpy(void *dest, void *src, size_t n)
{
char *csrc = (char *)src;
char *cdest = (char *)dest;
for (int i=0; i<n; i++)
cdest[i] = csrc[i];
}
int main()
{
char csrc[100] = "testCPY";
testMemcpy(csrc+5, csrc, strlen(csrc) );
printf("%s", csrc);
return 0;
}
输出结果为:testCtestCte。我们希望的结果是:testCtestCPY。
自实现支持内存重叠拷贝的函数
void myMemMove(void *dest, void *src, size_t n)
{
if(dest==NULL || src==NULL){
return;
}
char *csrc = (char *)src;
char *cdest = (char *)dest;
if(cdest >src && cdest< csrc+n){
while (n){
cdest[n-1] = csrc[n-1];
n--;
}
} else{
// Copy contents of src[] to dest[]
for (int i=0; i<n; i++){
cdest[i] = csrc[i];
}
}
}
int main()
{
char csrc[100] = "testCPY";
myMemCpy(csrc+5, csrc, strlen(csrc) );
printf("%s", csrc);
return 0;
}
注意事项
1)内存重叠会破坏源字符串的值。