关于实现memcpy和memmove两个库函数的一点体会

最近在论坛上看了一篇关于阿里巴巴面试题的帖子,让自己实现memcpy库函数,要求考虑特殊情况,两段内存存在覆盖,以及指针为空的情况。下面是我对此问题的几点看法(可能还有理解不到的地方)和最终修改的代码。


几点结论:
1,memcpy实现从源source中拷贝n个字节到目标destin中,src源数据应该保留。
2,memmove实现移动一块字节,src源数据可以不保留。
3,memcpy没有考虑内存覆盖问题(由assert条件可知);而memmove考虑了内存覆盖问题,并给出了解决办法。
4,memcpy和memmove中不需要考虑数组越界问题,dst的长度应该大于src的长度,这是调用者应该考虑的问题。


/* * 函数名: memcpy * 功 能: 从源source中拷贝n个字节到目标destin中 * 用 法: void *memcpy(void* destin, const void* source, size_t n); * 说 明: 自己实现此库函数 */ #include <stdio.h> //#include <string.h>//memcpy库函数头文件 #include <conio.h> //getch头文件 #include <assert.h> //assert头文件 typedef unsigned char byte; //typedef unsigned int size_t; /* memcpy自定义函数 */ //src要保留 void* memcpy(void* dst,const void* src,size_t count) { char* pbTo = (char*)dst; char* pbFrom = (char*)src; assert(dst!= NULL && src != NULL);//不能存在空指针 assert(pbTo >= pbFrom+count || pbFrom >= pbTo + count);//防止内存重叠(overlap) while (count-- > 0) { *pbTo++ = *pbFrom++; } return dst; } /* memmove自定义函数 */ //src可以不保留 void* memmove(void* dst,const void* src,size_t count) { char* pbTo = (char*)dst; char* pbFrom = (char*)src; assert(dst != NULL && src != NULL);//不能存在空指针 if (dst <= src || pbTo >= pbFrom + count)//没有overlap的情况,直接拷贝 { while (count-- > 0) { *pbTo++ = *pbFrom++; } } else { pbTo = pbTo + count -1;//overlap的情况,从高位地址向低位拷贝 pbFrom = pbFrom + count -1; while (count-- > 0) { *pbTo-- = *pbFrom--; } } return dst; } int main() { char src[]="*********"; char dst[]="abcdefghijklmnopqrstuvwxyz"; char *ptr; printf("destination before memcpy: %s/n",dst); //测试用例1 ptr=(char *)memcpy(dst,src,sizeof(src)/sizeof(char)); //测试用例2 //ptr=(char *)memmove(dst,src,sizeof(src)/sizeof(char)); //测试用例3 //ptr=(char *)memcpy(dst+1,dst,2);//memcpy没有考虑内存覆盖,如果出现覆盖assert报错 //测试用例4 //ptr=(char *)memmove(dst+1,dst,2);//memmove考虑了内存覆盖 if (ptr) { printf("destination after memcpy: %s/n",ptr); } else { printf("memcpy failed/n"); } getch(); return 0; }


修改用例测试:

/* Modification Date: 2010-3-17 Author: wcdj */ #include <cstdio> #include <string.h> // memcpy库函数头文件 #include <conio.h> // getch头文件 #include <assert.h> //assert头文件 typedef unsigned char byte; //typedef unsigned int size_t; /* memcpy自定义函数 */ //src要保留 void* memcpy(void* dst,const void* src,size_t count) { char* pbTo = (char*)dst; char* pbFrom = (char*)src; assert(dst!= NULL && src != NULL);//不能存在空指针 assert(pbTo >= pbFrom+count || pbFrom >= pbTo + count);//防止内存重叠(overlap) while (count-- > 0) { *pbTo++ = *pbFrom++; } return dst; } /* memmove自定义函数 */ //src可以不保留 void* memmove(void* dst,const void* src,size_t count) { char* pbTo = (char*)dst; char* pbFrom = (char*)src; assert(dst != NULL && src != NULL);//不能存在空指针 if (dst <= src || pbTo >= pbFrom + count)//没有overlap的情况,直接拷贝 { while (count-- > 0) { *pbTo++ = *pbFrom++; } } else { pbTo = pbTo + count -1;//overlap的情况,从高位地址向低位拷贝 pbFrom = pbFrom + count -1; while (count-- > 0) { *pbTo-- = *pbFrom--; } } return dst; } int main() { // test char src[]="123456"; char dst[]="abcdefghijklmnopqrstuvwxyz"; char *ptr; printf("destination before memcpy: %s/n",dst); //测试用例1 ptr=(char *)memcpy(dst,src,sizeof(src)/sizeof(char));// "123456" //ptr=(char *)memcpy(dst,src,strlen(src));// "123456ghijklmnopqrstuvwxyz" //测试用例2 //ptr=(char *)memmove(dst,src,sizeof(src)/sizeof(char));// "123456" //ptr=(char *)memmove(dst,src,strlen(src));// "123456ghijklmnopqrstuvwxyz" //测试用例3 //ptr=(char *)memcpy(dst+1,dst,2);//memcpy没有考虑内存覆盖,如果出现覆盖assert报错 //测试用例4 //ptr=(char *)memmove(dst+1,dst,2);//memmove考虑了内存覆盖 "abde...z" if (ptr) { printf("destination after memcpy: %s/n",ptr); } else { printf("memcpy failed/n"); } getch(); return 0; }


你可能感兴趣的:(面试,测试,null,阿里巴巴,byte,DST)