pit-rayの備忘録

開発中に得た知識を記事にしていくブログ

<C言語>memcpyとmemmoveの違い

本日はmemmoveとmemcpyの違いが気になり、調べていました。
memmoveとmemcpyはどちらもアドレスをコピーする関数(string.hに定義)です。

まず、代表的な違いを挙げてみます。
この二つの関数がオーバーラップ、つまり、コピー元を上書きする形でコピーする際(メモリブロックをずらすときなど)、memcpyは未定義の動作をします。つまり、memcpyは重複していると確実にコピーできない場合があります。一方でmemmoveは重複していても確実にコピーすることができます。
未定義の動作(undefined)が起きると、別の領域にアクセスしたりして、アクセス違反のエラーが吐かれたりします。セグメンテーション違反とか呼ばれてます。

ここで
memcpyの存在意義は何?
と疑問に思ったわけです。

先に調べた結果を書くと
memcpyはmemmoveよりも僅かに高速という意見が多く見受けられました。
私のサイトで一番アクセスされているmemset+mallocとcallocの違いは何か
pit-ray.hatenablog.com
という記事と同じような結果と言えます。


では調べたサイトなどを踏まえ書いていきます。
まず、このサイトをご覧ください。
stackoverflow.com
引用

122
down vote
accepted
With memcpy, the destination cannot overlap the source at all. With memmove it can. This means that memmove might be very slightly slower than memcpy, as it cannot make the same assumptions.

ここのページでの主な質問と回答は以下の通りです。
質問:memmoveとmemcpyの違いを教えてください。
回答:memcpyはコピー元(source)とコピー先(destination)を重複させる(overlap)ような使い方はできない。でもmemmoveはできる。これはmemcpyのほうが僅かに速いということでもある。
※訳しているわけではありません。

他の回答も載っていますが、検証付きの回答で、基本的には同じようなことが書かれているはずです。
このページだけでは不安なのでいくつか参考に載せておきます。
memmove
memcpy と memmove - a.out
c - memcpy() vs memmove() - Stack Overflow



ここでmemcpyがなぜmemmoveよりも速いのかということを掘り下げてみたいと思います。(先ほどのサイトの別回答に書かれていましたが、別に取り上げたいと思います)
ここで参考にさせていただいたサイトは以下の通りです。
標準Cライブラリの実装 memmove関数
c++ - Performance of memmove compared to memcpy twice? - Stack Overflow
c++ - Why is memmove faster than memcpy? - Stack Overflow
c - memcpy() vs memmove() - Stack Overflow

以上のサイトからみると、
memmoveはオーバーラップを正確に処理するために判定する機構を設けています。
そのため、memmoveはmemcpyよりも処理的に遅くなるみたいです。
また、memcpyはオーバーラップをしない環境では最良のアルゴリズムになっているというのも要因です。

よって、オーバーラップを確実にしない場合はmemcpyを使用することがプログラム的には良いと思われます。

ただリンクを貼っているだけの手抜き記事となりましたが、参考にしていただくと幸いです。
間違いがあったらコメントください。

それにしても、moveって単語的にコピーのイメージ無いから紛らわしいんだよなぁ...

では(@^^)/~~~