2012-11-12 4 views
10

Vom Linux-Manpage memmove(3)Warum wird Linux memove() so implementiert, wie es ist?

Die memmove() Funktion kopiert n Bytes aus dem Speicherbereich src zum Speicherbereich dest. Die Speicherbereiche können sich überlappen: Der Kopiervorgang erfolgt so, als ob die Bytes in src zuerst in ein temporäres Array kopiert werden, das src oder dest nicht überlappt, und die Bytes werden dann vom temporären Array nach dest kopiert.

stattdessen eine temporäre Anordnung der Zuteilung und kopieren Sie die Werte zweimal konnten wir nur Folgendes tun:

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; 
} 

In dieser Implementierung einfach wir kümmern uns um die Position bringen, wo wir zu kopieren beginnen.

Gibt es einen Nachteil in meiner Implementierung?

Hinweis: Ich werde meine Implementierung nicht verwenden. Ich bin nur Neugierig.

+4

'dest

+12

Ich denke, Sie haben "wie" in Manpage verpasst. Es funktioniert nicht so. – dbrank0

+0

Sie können Ihre Implementierung mit [FreeBSDs 'bcopy'] (http://fxr.watson.org/fxr/source/strc/copy.c?v=FEBEBSD-LIBC), dem zugrunde liegenden Code für ihre memmove(), vergleichen. Es unterstützt auch das Kopieren rückwärts ohne einen temporären Puffer. – ShiDoiSi

Antwort

22

Sie irgend Quellcode aussehen kann für memmove here, here, here und here.

Was Sie bemerken werden ist, dass sie nicht eigentlich ein temporäres Array machen. Die man-Seiten werden geschrieben, um Ihnen zu helfen, zu verstehen, was es tut logisch, nicht tatsächlich. Daher sagen sie "als ob".

Was memmove() tatsächlich tut, ist die Bytes von src zu dest kopieren und Kopien nach vorne, wenn dest < src (was im Wesentlichen dasselbe wie memcpy ist), und nach hinten anders.

Der Unterschied zwischen memcpy und memmove ist, dass memcpy blind Kopien nach vorn - deshalb dest und src sollten nicht überlappen. Aber memmove sorgt dafür, dass die Überlappung das Endergebnis nicht vermasselt.

+2

Ausgezeichnete Punkte. Die C-Quelle zu Linux memmove ist [hier] (http://sourceware.org/git/?p=glibc.git;a=blob;f=string/memmove.c;h=bf7dcc162770503ed62a262f627bfa526fc5a0d7;hb=HEAD), aber es ist weitgehend irrelevant, weil das eigentliche 'memmove' implementiert ist [in hand-optimierter Assembly] (http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/memcpy.S; h = 9e693f2a9806fa8f6ce7e26f37b1808e952396d3; hb = HEAD), die definitionsgemäß nicht in ein temporäres Array kopiert. Als eine Kuriosität ist es genau so definiert wie 'memcpy', weil es auf seiner Zielarchitektur keine Strafe dafür gibt. – user4815162342

Verwandte Themen