首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

下手实现memcopy函数

2013-10-10 
动手实现memcopy函数函数原型:MemCopy(void* from,void* to,int n)函数功能:把 from 指向的内存中的n个字

动手实现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));         }}

热点排行