【面試題】實現memcpy函數

面試中如問到memcpy的實現,那就要當心了,這裏有陷阱。c++

先看下標準memcpy()的解釋:面試

void *memcpy(void *dst, const void *src, size_t n);
//If copying takes place between objects that overlap, the behavior is undefined.

注意下面的註釋,對於地址重疊的狀況,該函數的行爲是未定義的。

事實上所說的陷阱也在於此,本身動手實現memcpy()時就須要考慮地址重疊的狀況。函數

另外,標準庫也提供了地址重疊時的內存拷貝函數:memmove(),那麼爲何還要考慮重寫memcpy()函數呢?code

由於memmove()函數的實現效率問題,該函數把源字符串拷貝到臨時buf裏,而後再從臨時buf裏寫到目的地址,增長了一次沒必要要的開銷。內存

下面給出memcpy()的實現,爲了與標準庫函數區分,咱們實現其包裹函數:字符串

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void *Memcpy(void *dst, const void *src, size_t size);

int main(int argc, char *argv[])
{
    char buf[100] = "abcdefghijk";
    //memcpy(buf+2, buf, 5);
    Memcpy(buf+2, buf, 5);
    printf("%s\n", buf+2);
}

void *Memcpy(void *dst, const void *src, size_t size)
{
    char *psrc;
    char *pdst;

    if(NULL == dst || NULL == src)
    {
        return NULL;
    }

    if((src < dst) && (char *)src + size > (char *)dst) // 自後向前拷貝
    {
        psrc = (char *)src + size - 1;
        pdst = (char *)dst + size - 1;
        while(size--)
        {
            *pdst-- = *psrc--;
        }
    }
    else
    {
        psrc = (char *)src;
        pdst = (char *)dst;
        while(size--)
        {
            *pdst++ = *psrc++;
        }
    }

    return dst;
}

使用Memcpy()的結果:string

abcdehijk

使用memcpy()的結果:

abadehijk

能夠看到標準庫函數的源字符串在拷貝的過程當中被污染了。

2011-12-02 任洪彩 qdurenhongcai@163.comio

轉載請註明出處.class

相關文章
相關標籤/搜索