【题目】
已知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;
}