18

memmove(3)の Linux マンページから

memmove() 関数は、メモリ領域 src からメモリ領域 dest に n バイトをコピーします。メモリ領域はオーバーラップする場合があります。コピーは、src 内のバイトが最初に src または dest とオーバーラップしない一時配列にコピーされ、次にバイトが一時配列から dest にコピーされるかのように行われます。

一時的な配列を割り当てて値を 2 回コピーする代わりに、次のようにすることができます。

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

1 に答える 1

38

memmove のソース コードは、ここここここ、およびここで見ることができます。

お気づきのことと思いますが、これらは実際には一時的な配列を作成していません。man ページは、実際にではなく論理的に何をしているのかを理解するのに役立つように書かれています。したがって、彼らは「まるで」と言います。

memmove() が実際に行うことは、バイトを から にコピーするsrcことdestであり、場合は前方にコピーしdest < src(これは基本的に memcpy と同じです)、それ以外の場合は後方にコピーします。

memcpyとの違いmemmoveは、memcpyやみくもに前方にコピーすることです。これが、destsrcがオーバーラップしてはならない理由です。ただしmemmove、オーバーラップが最終結果を台無しにしないように注意してください。

于 2012-11-12T07:39:30.507 に答える