【1】内存拷贝函数应该如何实现?
函数原型:void * memcpy(void *memTo,memFrom,size_t size)
返回值类型:void *
参数1:void *memTo; 需要拷入的目的指针
参数2:void *memFrom; 需要拷贝的起始指针
参数3:size_t size; size_t代表unsigned int 表示拷贝的字节数
(1)具体实现版本V1.0。示例代码如下:
1 void * memcpy(void *memTo, const void *memFrom, size_t size) 2 { 3 assert((memTo != NULL) && (memFrom != NULL)); 4 char *tempFrom = (char *)memFrom; 5 char *tempTo = (char *)memTo; 6 while (size-- > 0) 7 { 8 *tempTo++ = *tempFrom++; 9 }10 return memTo;11 }
但是,如果用户如下调用就会出错。请看下面这种情况,两种版本的比较:
(2)具体改进实现V2.0。示例代码如下:
1 #include2 #include 3 using namespace std; 4 5 void * MyMemMove(void *dst, const void *src, int count) 6 { 7 assert((dst != NULL) && (src != NULL)); 8 char* tempFrom = (char *)src; 9 char* tempTo = (char *)dst;10 if (tempTo <= tempFrom || tempTo >= (tempFrom + count)) 11 {12 while (count--) 13 {14 *tempTo++ = *tempFrom++;15 }16 }17 else 18 {19 tempTo = tempTo + count - 1;20 tempFrom = tempFrom + count - 1;21 while (count--) 22 {23 *tempTo-- = *tempFrom--;24 }25 }26 return dst;27 }28 29 void *memcpy(void *memTo, const void *memFrom, size_t size)30 {31 assert((memTo != NULL) && (memFrom != NULL));32 char *tempFrom = (char *)memFrom;33 char *tempTo = (char *)memTo;34 while (size-- > 0)35 {36 *tempTo++ = *tempFrom++;37 }38 return memTo;39 }40 41 void main()42 {43 char p1[256] = "hello,world!";44 char p2[256] = "hello,world!";45 MyMemMove(p1 + 1, p1, sizeof(p1));46 memcpy(p2 + 1, p2, sizeof(p2));47 cout << p1 << endl; //hhello,world!48 cout << p2 << endl; //hhhhhhhhhhhhhh..... error!!!!!49 system("pause");50 }
OK,如果用户如上调用的话,版本V1.0问题显而易见,也就是所谓的重叠内存拷贝。
这个时候就要考虑拷贝的起始地址与目的地址的大小关系。首先就要进行一步判断。如上例所示。
(3)因为内存拷贝可能不仅仅是几十个字节的任务,在实际的工作中,面对大量的字节拷贝,我们也要防止用户输入比较极端,不小心把起始地址与目的地址输入成了一个地址,那么,为了不浪费cpu做无用功。最后综合考虑,再判断一下两个指针的异同。
所以,比较满意实现V3.0。示例代码如下:
1 void * MemMove(void *dst, const void *src, int count) 2 { 3 assert((dst != NULL) && (src != NULL)); 4 char* tempFrom = (char *)src; 5 char* tempTo = (char *)dst; 6 if (tempTo <= tempFrom || tempTo >= (tempFrom + count)) 7 { 8 while (count--) 9 {10 *tempTo++ = *tempFrom++;11 }12 }13 else 14 {15 tempTo = tempTo + count - 1;16 tempFrom = tempFrom + count - 1;17 while (count--) 18 {19 *tempTo-- = *tempFrom--;20 }21 }22 return dst;23 }
另外....