memcpy实现内存重叠的拷贝

上周面试腾讯的时候,面试官问我内存的拷贝,当时答错了,因为没有用过内存拷贝函数。

面试官叫我实现内存拷贝函数,同时问我出现了内存重叠怎么办?

什么叫内存重叠呢?我画个图

memcpy实现内存重叠的拷贝_第1张图片

比如要拷贝src的4个字节到dest,那么就出现了内存重叠,如果从头开始拷贝,那么dest把src覆盖掉了。自己实现一款memcpy函数就是

void* Memcpy1(void* dst,const void* src,int count)
{
    assert(dst!=nullptr && src!=nullptr);
    void* ret = dst;
    while(count--)
    {
        *(char*)dst =*(char*)src;
        dst = (char*)dst+1;
        src = (char*)src+1;
    }
    return ret;
}

int main()
{
    char str[] = {"abcdefgh"};
    Memcpy1(str+2,str,5);
    printf("%s\n%s\n",str,str+2);
    return 0;
}

我们看看重叠后运行结果为:
memcpy实现内存重叠的拷贝_第2张图片
我们原本想得到的是abcde,结果现在是是ababa,因为我们最开始把src覆盖掉了。

所以当出现内存覆盖的时候,我们应该从后向前复制,那么我们才能得到正确的copy结果。

所以判断边界条件也就是内存覆盖的条件是:

if(dst<=src || (char*)dst>=((char*)src+count)

内存拷贝代码为:

void* Memcpy(void* dst,const void* src,int count)
{
    assert(dst!=nullptr && src!=nullptr);
    void* ret = dst;
    if(dst<=src || (char*)dst>=((char*)src+count))
    {
        while(count--)
        {
            *(char*)dst =*(char*)src;
            dst = (char*)dst+1;
            src = (char*)src+1;
        }
    }
    else
    {
        dst = (char*)dst + count -1;
        src = (char*)src + count -1;
        while(count--)
        {
            *(char*)dst = *(char*)src;
            dst = (char*)dst-1;
            src = (char*)src-1;
        }
    }
    return ret;
}

运行结果为:

memcpy实现内存重叠的拷贝_第3张图片

就可以复制成功了。

你可能感兴趣的:(面试题小节)