C++笔试题集:实现memcpy
in 代码 with 0 commentand 368 read

C++笔试题集:实现memcpy

in 代码 with 0 commentand 369 read

最近一直周转在成都街头,拿着我的简历四处碰壁,真不知道何时才是个头,不管了,闯咯
经历了很多场笔试面试之后,却也很直观的挖出了我知识上的不足。对C++认识的上也有很大偏差
下面我列出来我之前遇到过的比较坑的题目,自认为还需要成长的的地方

实现memcpy

void * memcpy(void *dest, const void *src, size_t size)
当时我脑中的答案

void * memcpy(void * dest, const void * src,size_t size)
{
    if (dest == NULL && src == NULL)
    {
        return NULL;
    }
    char * CopyDest = dest;
    while (size--)
        *CopyDest++ = *src++;
    dest  = NULL;
    return CopyDest;
}

一开始没注意,等到我笔试结束的时候,我搜了一下才发现事情往往没有那么简单

  1. 如果dest和src的指针类型不一样,不能直接++赋值;
  2. 如果dst和src地址不对齐,效率会降低
  3. dest和src所指向的内存空间不能重叠,否则复制的数据是错误的

内存重叠问题是指目的地址的内存空间的首地址,包含在源内存空间中,这两段内存空间有了交集,因而在使用memcpy进行内存复制操作时,这段重叠的内存空间会被破坏.这种情况在应用程序级代码中一般不会出现的,而在驱动或内核级代码中要十分小心,尽量使用memmove函数.

重叠内存模型
20150507143710523.png
src所指向的内存空间后面部分数据被新拷贝的数据给覆盖了(也就是dest<=src+size).所以拷贝到最后,原来的数据肯定不是原来的数据,拷贝的数据也不是想要的数据,使用memcpy函数可以得到错误的结果.

虽然原来的数据不再是原来的数据(dest+size>=src),但拷贝的数据是原来的数据,使用memcpy函数可以得到正确的结果.因此,在使用memcpy这个函数之前,还需要做一个判断,如果dest<=src你才能使用这个函数不过完全没有必要, 解决办法:从高地址向低地址copy

void * memcpy(void *dest, const void *src, size_t size)
{
    char *psrc;
    char *pdst;

    if (NULL == dest || NULL == src)
    {
        return NULL;
    }
    if ((src < dest) && (char*)src + size > (char *)dest)//自高地址向前拷贝
    {
        psrc = (char *)src + size - 1;
        pdst = (char *)dest + size - 1;
        while (size--)
        {
            *pdst-- = *psrc--;
        }
    }
    else
    {
        psrc = (char *)src;
        pdst = (char *)dest;
        while (size--)
        {
            *pdst++ = *psrc++;
        }
    }
    return dest;
}
评论