下手实现memcopy函数

动手实现memcopy函数

函数原型:MemCopy(void* from,void* to,int n);
函数功能:把 from 指向的内存中的n个字节复制到to指向的内存中。
分析:这个有个陷阱就是 to 和  from 两个地址谁大谁小,以及是否重叠。我们假设两段内存地址范围为:  from ~ from +(n-1), to ~ to+(n-1)(长度都为 n ),为了说明下面的情形,我们举一个例: 数组  array[8]={0,1,2,3,4,5,6,7};
情形1:【举例 from = array,to = arary+4 ,n=3】
 from  +(n-1) < to  或者  to+(n-1) < from   ,即两段内存没有任何重合,这时
从 头部  from  开始拷贝到尾部 from+(n-1),
即 *from->*to , *(from+1)->*(to+1) ... *(from+(n-1)) -> *(to+(n-1)) 
或者
从尾部from+(n-1) 开始拷贝到 from ,
即*(from+(n-1)) -> *(to+(n-1))  ...   *(from+1)->*(to+1) ,*from->*to
都是没有问题。结果都是 :array[8]={0,1,2,3,0,1,2,7};
换句话说你可以正向拷贝,也可以反向拷贝。
情形2:【举例 from = arrary,to=array+2,n=3】
 from < to <from +(n-1),即两段内存有重合,并且要被拷贝的数据地址(from)在要拷贝到的地址(to)的前面,这时:
从 头部  from  开始拷贝到尾部 from+(n-1),
即 *from->*to , *(from+1)->*(to+1) ... *(from+(n-1)) -> *(to+(n-1)) 
结果:array[8]={0,1,0,1,0,1,2,7}; 不是我们期待的结果(第三个0是错误拷贝结果)。
或者
从尾部from+(n-1) 开始拷贝到 from ,
即*(from+(n-1)) -> *(to+(n-1))  ...   *(from+1)->*(to+1) ,*from->*to。
结果:array[8]={0,0,1,2,0,1,2,7};是我们期待的结果。换句话说你只可以反向拷贝。
情形3:【举例 from = arrary+2,to=array,n=3】
 to  < from< to  +(n-1),即两段内存有重合,并且要被拷贝的数据地址(from)在要拷贝到的地址(to)的后面,这时:
从 头部  from  开始拷贝到尾部 from+(n-1),
即 *from->*to , *(from+1)->*(to+1) ... *(from+(n-1)) -> *(to+(n-1)) ;
结果:array[8]={2,3,4,3,4,5,6,7};是我们期待的结果。
或者
从尾部from+(n-1) 开始拷贝到 from ,
即*(from+(n-1)) -> *(to+(n-1))  ...   *(from+1)->*(to+1) ,*from->*to。
结果:array[8]={4,3,4,3,4,5,6,7};不是我们期待的结果(第一个4是错误拷贝结果)。换句话说你只可以正向拷贝。
在纸上画一下图,把三种情形都表示出来,然后考虑两种拷贝顺序(从头开始和从尾部开始),一共 3*2 六种情况,就明白了。
以上所有的讨论是基于to和from所指空间的大小都大于等于n。
void MemCopy(void* from,void* to,int n)
{
         if(from==NULL||to==NULL||n<0)
                return;
         int i;
         if(from<=to)
         {
                for(i=n-1;i>=0;i--)
                     *((char *)(to+i)) = *((char *)(from+i));
         }
         else
         {
                for(i=0;i<n;i++)
                     *((char*)(to+i)) = *((char*)(from+i));
         }
}