2012-11-12 70 views
10

從Linux聯機幫助頁memmove(3)爲什麼Linux memmove()以這種方式實現?

的的memmove()函數拷貝n個字節從存儲器區域的src到存儲器區域DEST。 存儲區可能重疊:複製發生,就好像src中的字節是 首先被複制到與src或dest不重疊的臨時數組中,然後 字節從臨時數組複製到dest。

不是分配一個臨時數組複製值的兩倍,我們可能只是做到以下幾點:

void *my_memmove(void *dest, const void *src, size_t n) { 
    signed char operation; 
    size_t end; 
    size_t current; 

    if(dest != src) { 
    if(dest < src) { 
     operation = 1; 
     current = 0; 
     end = n; 
    } else { 
     operation = -1; 
     current = n - 1; 
     end = -1; 
    } 

    for(; current != end; current += operation) { 
     *(((unsigned char*)dest) + current) = *(((unsigned char*)src) + current); 
    } 
    } 
    return dest; 
} 

在此實現,我們只是拿我們開始複製位置的照顧。

我的實施有沒有缺點?

注意:我不會實際使用我的實現。我只是好奇。

+4

當dest和src指向不同的塊時,dest 是未定義的行爲。當'dest'和'src'指向同一個塊時,函數'memmove()'被指定爲工作,但沒有指定它必須用指向同一個塊的指針來調用。看到相關的問題http://stackoverflow.com/questions/4023320/how-to-implement-memmove-in-standard-c-without-an-intermediate-copy –

+12

我想你錯過了「好像」在手冊頁。它實際上並不這樣。 – dbrank0

+0

您可以將您的實現與[FreeBSD的'bcopy'](http://fxr.watson.org/fxr/source/string/bcopy.c?v=FREEBSD-LIBC),它們的memmove()的底層代碼進行比較。它也支持向後複製,沒有臨時緩衝區。 – ShiDoiSi

回答

22

你可以看一些源代碼的memmove herehereherehere

你會注意到的是,他們不會實際上做一個臨時數組。寫手冊頁是爲了幫助你理解它在做什麼邏輯上,而不是實際上。因此,他們說「好像」。

什麼的memmove()實際上做的是字節複製從srcdest,並將其複製着,如果dest < src(這基本上是同樣的事情的memcpy),並且向後否則。

memcpymemmove之間的區別是,memcpy盲目拷貝前鋒 - 這就是爲什麼destsrc不能重疊。但memmove採取預防措施,確保重疊不會搞砸最終結果。

+2

優秀點。 Linux memmove的C源代碼是[here](http://sourceware.org/git/?p=glibc.git;a=blob;f=string/memmove.c;h=bf7dcc162770503ed62a262f627bfa526fc5a0d7;hb=HEAD),但它在很大程度上是不相關的,因爲實際的'memmove'實現了[手動優化程序集](http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/memcpy.S; h = 9e693f2a9806fa8f6ce7e26f37b1808e952396d3; hb = HEAD),它絕對不會複製到臨時數組。作爲好奇心,它的定義與'memcpy'完全相同,因爲在其目標架構中,這樣做不會有任何處罰。 – user4815162342

相關問題