面試中如問到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