【题目】
已知memcpy的函数为: void* memcpy(void *dst , const void* src , size_t count)
其中dst是目的指针,src是源指针。不调用c++/c的memcpy库函数,请编写memcpy。
-------百度,网新恒天校园招聘
【解析】
1 按照ANSI(American National Standards Institute)标准,不能对void指针进行算法操作,
即不能对void指针进行如p++的操作,所以需要转换为具体的类型指针来操作,例如char *
2 memcpy是对内存进行操作,可能遇到内存重叠的情况,同样的问题存在于memmove中, 但是源代码中这两个函数的处理方式不一样:
memcpy中dst和src中的区域不能重叠,否则会出现未知结果。函数没做任何内存的处理,内存是否重叠由程序员自己控制。
memmove里面则判断了内存重叠的情况,当内存重叠时从后往前复制,以确保复制正常处理。
【代码】
#include <iostream> using namespace std; //实现memcpy库函数 void* memcpy(void *dst, const void *src, size_t count){ // 容错处理 if(dst == NULL || src == NULL){ return NULL; } unsigned char *pdst = (unsigned char *)dst; const unsigned char *psrc = (const unsigned char *)src; //判断内存是否重叠 bool flag1 = (pdst >= psrc && pdst < psrc + count); bool flag2 = (psrc >= pdst && psrc < pdst + count); if(flag1 || flag2){ cout<<"内存重叠"<<endl; return NULL; } // 拷贝 while(count--){ *pdst = *psrc; pdst++; psrc++; } return dst; } int main(){ char c1[] = "hello world"; memcpy(c1+3, c1, 9); cout<<"memcpy result:"<<c1<<endl; char c2[] = "love you"; memcpy(c1,c2,8); cout<<"memcpy result:"<<c1<<endl; }
#include <iostream> #include <string.h> using namespace std; //实现memmove库函数 void* memmove(void *dst, const void *src, size_t count){ // 容错处理 if(dst == NULL || src == NULL){ return NULL; } unsigned char *pdst = (unsigned char *)dst; const unsigned char *psrc = (const unsigned char *)src; //判断内存是否重叠 bool flag1 = (pdst >= psrc && pdst < psrc + count); bool flag2 = (psrc >= pdst && psrc < pdst + count); if(flag1 || flag2){ // 倒序拷贝 while(count){ *(pdst+count-1) = *(psrc+count-1); count--; }//while } else{ // 拷贝 while(count--){ *pdst = *psrc; pdst++; psrc++; }//while } return dst; } int main(){ // 内存重叠 char c1[] = "hello world"; memmove(c1+3, c1, 8); cout<<"memmove result:"<<c1<<endl; // 内存不重叠 char c2[] = "hello world"; char c3[] = "love you"; memmove(c2,c3,8); cout<<"memmove result:"<<c2<<endl; }
#include <iostream> using namespace std; void* memmove(void* str1,const void* str2,size_t n){ char* pStr1= (char*) str1; const char* pStr2=(const char*)str2; // 正序拷贝 if (pStr1 < pStr2) { for(size_t i=0;i!=n;++i){ *(pStr1++)=*(pStr2++); } } // 倒序拷贝 else{ pStr1+=n-1; pStr2+=n-1; for(size_t i=0;i!=n;++i){ *(pStr1--)=*(pStr2--); } } return pStr1; } int main(){ char str[] = "hello world"; memmove(str+4,str,7); cout<<str<<endl; return 0; }