memmoveは実際にはメモリを動かしませんよね?ある領域から別の領域にメモリをコピーするだけで、これら2つの領域をオーバーラップさせることができます。このfncが非常に誤解を招く方法で呼び出される理由を知りたいので、この質問をしています。
ある場所から別の場所に何かを移動するとき、「もの」は最初の場所ではなく、別の場所でのこの操作の後にあることを私は理解しています。そして、memmoveではそのようには機能しません。私は正しいですか?
7 に答える
あなたは正しいです、それはそれをコピーします。ただし、とには違いがmemmove
あります。これは、バッファがオーバーラップしている場合を正しく処理できるため、これらの場合に推奨されますmemcpy
。memmove
ただし、追加のチェックがmemmove
実行されるため、バッファが小さく、確実にオーバーラップしない場合のmemcpy
方が適しています。
memcpy()
との違いはmemmove()
、memmove()
送信元と宛先の間のエイリアシングに関係なく、常に安全に使用できることです。これは、memmove()
データを最初に一時バッファにコピーし、次に宛先にコピーするかのようです。 memcpy()
エイリアシングの保証はありません。意図したとおりに機能する場合もありますが、そうでない場合もあります。バッファがオーバーラップできないことがわかっている場合memcpy()
は、問題なく、特定のライブラリで最適化を使用して、より高速にすることができますmemmove()
。別のライブラリmemcpy()
では、実際にはmemmove()
。
srcとdstをエイリアスにできないことがわかっている場合は、を使用しても安全memcpy()
です。どちらが当てはまるかわからない場合は、を使用してくださいmemmove()
。
この関数は、コピーされるメモリ領域がたまたまオーバーラップした場合、元のバッファが変更されていないため、コピーではなくなるため、そのように名付けられています。したがって、元のバッファは使用できないと見なす必要があります。memcpyではなくmemmoveを使用しているので、これが当てはまる可能性があります。したがって、名前付けには意味があります。意味的には、データをコピーするのではなく移動することになります。
はい、memmove
実際memcpy
には重複するブロックを処理する機能があります。配列があり、最初にいくつかの新しいアイテムを挿入したい(またはいくつかのアイテムを削除したい)場合、同義的に、(既存または残りの)アイテムを前後に「移動」しているとしましょう-私は推測します、そしてその文脈では、名前は理にかなっています。
はい、memmove
コピーの別のバリエーションです。元のバイトが操作前のバイトではなくなったという意味で、メモリを「移動」することはありません。特に、メモリが重複している場合を処理します。
これがどのように行われるかはアーキテクチャによって異なりますが、2つの異なる方法で行われるのを見てきました。
- 2つのmemcpyタイプの操作で一時バッファーを使用します。また
- オーバーラップタイプ(存在する場合)に応じて、最初のバイトから前方に、または最後のバイトから後方にコピーします。
の名前についての質問に答えるにmemmove()
は:この名前は、配列内の要素の範囲を配列内の別の範囲に移動するためのサポートを反映することを意図したものだと思います(たとえば、配列の先頭または内部に新しい要素のためのスペースを作るため) )。
他の回答が述べているように、オーバーラップするメモリ領域をサポートしていないためmemcpy()
に利用できない最適化手法を使用できますが、サポートしています。memmove()
memcpy()
memmove()
コピーのパフォーマンスが重要なアプリケーションで作業している場合を除いて、デフォルトではmemmove()
なく、引き続き使用することを検討してください。より良いパフォーマンスを提供できます(主に、より効果的にインライン化できるためです)が、アプリケーションによるCライブラリの誤った使用に関する議論からのLinuxカーネルでの実装に関するこの引用を覚えておいてください:memcpy()
memcpy()
memcpy()
memcpy()
カーネルでは、使用する最適化されたx86 memcpyは実際にはmemmove()です。これは、パフォーマンスが非常に重要であると同時に、再現性と驚きの回避も重要であるためです(厳密に言えば、2つあります。高速で、オープンコード化されたコピーバージョンであると想定されています。「repmovs」バージョンは転送専用であり、重複する領域を処理しません)。