memcpyソースコードと書かれたテストの実装



Memcpy Source Code Written Test Implementation



記事のディレクトリ

memcpy関数

  • memcpy関数は、CおよびC ++で使用されるメモリコピー関数を指します。関数プロトタイプはvoid * memcpy(void * destin、void * source、unsigned n)関数の関数は、ソースメモリアドレスセクションの開始位置からターゲットメモリアドレスにいくつかのワードをコピーすることです。つまり、nをコピーします。ソースソースからターゲットデスティンまでのバイト。

memcpyソースコード

void *memcpy(void *dst, const void *src, size_t len) { if(NULL == dst || NULL == src){ return NULL } void *ret = dst if(dst <= src || (char *)dst >= (char *)src + len){ //No memory overlap, copy from the lower address while(len--){ *(char *)dst = *(char *)src dst = (char *)dst + 1 src = (char *)src + 1 } }else{ //There is memory overlap, copy from the high address src = (char *)src + len - 1 dst = (char *)dst + len - 1 while(len--){ *(char *)dst = *(char *)src dst = (char *)dst - 1 src = (char *)src - 1 } } return ret }

memcpy関数を書き直します

  • memcpy()関数を手動で実装する場合は、アドレスの重複を考慮する必要があります。簡単な例を見ることができます。 int arr = {1、2、3、4、5}として設定された5つの要素で構成される配列は、次の2つの場合を考慮します。
    (1)送信元アドレスはarr [2]、宛先アドレスはarr [0]、3つの要素を後ろから前にコピーした後、arrは[3,4,5,1,2]です。
    (2)送信元アドレスはarr [0]、宛先アドレスはarr [2]、3つの要素を連続してコピーした後、arrは{1,2,1,2,3}です。
  • 最初のケースでは、ソースアドレスの要素をターゲットアドレスの下位アドレスから上位アドレスに1つずつコピーします。これは、実装が簡単です。
  • 2番目のケースでは、注意を払う必要があります。最初のケースに従って下位アドレスから上位アドレスにコピーする場合は、arr [0] = 1、arr [1] = 2、arr [2] = 3を3つのステップに分割する必要があります。3つの要素がコピーされます。一つずつ。重要なのは、最初のステップはarr [0]をarr [2]の位置にコピーすることです。これにより、元のarr [2] = 3がarr [2] = 1に変更され、元の値が上書きされます。場合によっては、後ろから前にコピーする必要があります。つまり、上位アドレスから下位アドレスにコピーする必要があります。つまり、最初のステップはarr [2]をarr [4]に入れることです。2番目のステップはarr [1]をarr [3]に入れることです。3番目のステップはarr [0]をarr [2]に入れることです。
  • 具体的なコードは次のとおりです。
void *Memcpy(void *dst,const void *src,size_t size) { char *psrc //source address char *pdst //target address if(NULL == dst || NULL == src) { return NULL } //The source address is first, corresponding to the above situation 2, it needs to be copied from back to front if((src < dst)&&(char *)src+size > (char *)dst) { psrc = (char *)src + size - 1 pdst = (char *)dst + size - 1 while(size--) { *pdst-- = *psrc-- } } else //The source address is behind, corresponding to the first case above, just copy them one by one *pdst++=*psrc++ { psrc = (char *)src pdst = (char *)dst while(size--) { *pdst++ = *psrc++ } } return pdst }

テスト

#include #include #include void *Memcpy(void *dst,const void *src,size_t size) { char *psrc //source address char *pdst //target address if(NULL == dst || NULL == src) { return NULL } //The source address is first, corresponding to the above situation 2, it needs to be copied from back to front if((src < dst)&&(char *)src+size > (char *)dst) { psrc = (char *)src + size - 1 pdst = (char *)dst + size - 1 while(size--) { *pdst-- = *psrc-- } } else //The source address is behind, corresponding to the first case above, just copy them one by one *pdst++=*psrc++ { psrc = (char *)src pdst = (char *)dst while(size--) { *pdst++ = *psrc++ } } return pdst } int main() { char s[16] = 'aabbcc' char d[16] = {0} Memcpy(s+2,s,4) printf('Memcpy : %s ',s) strcpy(s,'aabbcc') memcpy(s+2,s,4) printf('memcpy: %s ',s) return 0 }

出力結果:
画像