關於memcpy的實現


今天去面試,面試官出了一個關於memcpy的函數原型的實現的問題,本來這個問題是很簡單的,但是不知道當時怎么腦子一抽竟然寫錯了,真是”累覺不愛”了.感覺這份工作算是泡湯了,算了事情發生了,錯過了也就錯過了.既然這樣就把這件事情記錄下來,給自己提個醒~

這個問題對於接觸過的朋友自然不難,問題在於給自己一個分析的方法,遇到類似的問題怎么解決.

memcpy實現內存拷貝,根據這個問題,我們可以提取出下面幾點:

1.可以拷貝任何數據,數據類型不能受限

2.源數據不能被改變

通過上面兩點可以確定函數原型為void *memcpy(void *dest, const void *src),現在分析一下這些足夠了嗎?這個函數拷貝什么時候結束,當時我就用了這個函數原型,由於是拷貝的任意數據,所以不能指定一個明確的結束標志,既然這樣那么只有明確的指定拷貝的大小才可以.所以函數原型變成這樣void *memcpy(void *dest, void *src, size_t count);好吧,函數原型既然已經確認了,剩下的應該就是寫函數了,先等等,先別急着寫函數,實際上對於C語言的開發者來說,重要的不是函數功能的實現,重要的是函數出錯時的處理,如果你用的是Java或者C#大不了拋個異常出來,軟件崩潰一下,不會對其他造成任何影響;C這東西弄不好會把整個系統弄癱瘓,所謂”兵馬未動,糧草先行”,我么還是先考慮考慮出錯的問題吧!我們根據函數原型來分析,

void *memcpy(void *dest, const void *src, size_t count);

1.空指針的問題,如果dest、src兩者或者兩者之一為NULL,那么自然能沒得完了;

2.拷貝大小count為小於等於0的值,自然也是不正確的;

3.目標有沒有足夠的大小容納源數據,這個我們在函數內部似乎也無法進行保證,但是我們自己也要想到

4.內存地址有沒有重疊,這個我們暫時不考慮了。

有了上面的提示寫起來自然比較簡單了

#include <stdio.h>

void *memcpy(void *dest, const void *src, size_t count)

{

if (NULL == dest || NULL == src || count <= 0)

return NULL;

while (count--)

*dest++ = *src++;

return dest;

}

上面這段代碼在Linux中使用gcc編譯是沒錯的,但是會有警告,所以改成這樣:

#include <stdio.h>

void *memcpy(void *dest, const void *src, size_t count)

{

if (NULL == dest || NULL == src || count <= 0)

return NULL;

while (count--)

*(char *)dest++ = *(char *)src++;

return dest;

}

OK,也就這樣了,要是面試官再問起內存重疊的問題,你再和他侃侃.

我的面試算是泡湯了.

總結:不要着急慢慢來,根據需求推出原型,根據原型推斷問題,這算是個教訓吧!!!

 

 

補充:

在這里非常感謝博客園的求道於盲  這位好心的網友指出了我程序中的兩個錯誤,再次感謝.

1.返回了一個++過的指針

2.size_t是無符號類型的,size_t的定義為:typedef unsigned int size_t;

所以count<=0,只會判斷==0的情況,如果傳入-1,會產生一個很大的無符號整型.

希望別人注意,改過的程序如下:

void *memcpy(void *dest, const void *src, int count)

{

void *ptr = dest;

if (NULL == dest || NULL == src || count <= 0)

return NULL;

 

while (count--)

*(char *)dest++ = *(char *)src++;

 

return ptr;

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM