memcpyでコピー中にコピー先とコピー元の領域がかぶる場合はどうなるの?

未定義です。
コピーの仕方に原因があります。


ためしにこんなコードを書いてみた。
http://codepad.org/J4xutzdQ

Hello Hello Hello H
Hello Hello World!


太い矢印がコピー元、細い矢印がコピー先を示しているとすると、前からコピーした場合、

H e l l o W o r l d ! \0

6文字目までコピー終わった時、

H e l l o H e l l o \0

こんな感じになります。


この動作から、僕の環境のmemcpyは前からコピーを行っていることが判ります。
前からコピーすると"World!"の部分が"Hello "に置き換わってしまい、
"World!"の部分をコピーし始める頃にはその部分が"Hello "になっているからです。
一方、後ろからコピーする方式をとったところ、うまくいきます。


今回の例では後ろからのコピーが良いのですが、
コピー元がコピー先よりも後ろにあった場合は、今度は後ろからのコピーでは問題が発生します。
このときは、前からのコピーでうまくいきます。


どちらのコピー方法をとればいいのかを判定するには、アドレスの値を比べることでわかります。
「コピー先>コピー元+コピーする長さ」であれば、コピー先とコピー元がかぶる事はないので、前からのコピーしても問題ありません。
ただ、memrcpyは1byteずつのコピーを行うので、速度面でmemcpyと比べると不利なので、
コピー先のアドレスからコピー元のアドレスを引いて、絶対値をとり、その値がコピーする長さより、短ければ、memcpyを使うようにしても良いでしょう。


最後に、普通memcpyを使うときに、同じ配列の領域内のアドレスからコピー先とコピー元を出すことはあまりないので、今回の問題は気にならないと思います。
ただ、はてな記法でテーブルを書いてみたかっただけでこの記事を書きました。