void *mymemcpy(void *dest, const void *src, unsigned int count)
{
assert(dest);
assert(src);
if ( ((char*)dest - (char*)src < count ) && (dest >= src) )
{
char *tempDest = (char*)dest + count - 1;
const char* tempSrc = (const char*)src + count - 1;
while (count-- > 0)
{
*tempDest = *tempSrc;
tempDest--;
tempSrc--;
}
}
else
{
char *tempDest = (char*)dest;
const char* tempSrc = (const char*)src;
while (count-- > 0)
{
*tempDest = *tempSrc;
tempDest++;
tempSrc++;
}
}
return dest;
}
今天看到一道题目让实现memcpy函数。我用手写试了一下,然后再用机器调试,果然自己功夫不扎实,出了问题,考虑的也不全面。在看了别人的文章之后,重新写了一遍,并记录下来,以免自己以后忘记了。
if ( ((char*)dest - (char*)src < count ) && (dest>=src) )
这句判断dest和src占用空间是否有重叠。如下图所示,绿色区域为src占用空间。当dest位于绿色区域时,需要从src的末端开始复制,否则会导致src的内容被覆盖。dest位于其他位置时,从src的起始端开始复制。内存重叠的情况容易被忽略。
上面的代码虽然实现了功能,但是在有的编译器下会报很多warning,修改之后如下:
void *mymemcpy(void *dest, const void *src, size_t count)
{
if (dest == nullptr || src == nullptr)
{
return nullptr;
}
auto tempDistance = static_cast<char*>(dest) - static_cast<const char*>(src);
if ( tempDistance > 0 && static_cast<size_t>(tempDistance) < count )
{
char *tempDest = static_cast<char*>(dest) + count - 1;
const char* tempSrc = static_cast<const char*>(src) + count - 1;
while (count-- > 0)
{
*tempDest = *tempSrc;
tempDest--;
tempSrc--;
}
}
else
{
char *tempDest = static_cast<char*>(dest);
const char* tempSrc = static_cast<const char*>(src);
while (count-- > 0)
{
*tempDest = *tempSrc;
tempDest++;
tempSrc++;
}
}
return dest;
}
调用如下:
int ma=10; int mb; mymemcpy(&mb, &ma, sizeof(ma)); cout<<mb<<endl; const char *maa = static_cast<const char*>("hello world"); char mbb[16]; mymemcpy(mbb, maa, strlen(maa)); cout<<mbb<<endl;
参考文章: