4

memmoveは実際にはメモリを動かしませんよね?ある領域から別の領域にメモリをコピーするだけで、これら2つの領域をオーバーラップさせることができます。このfncが非常に誤解を招く方法で呼び出される理由を知りたいので、この質問をしています。
ある場所から別の場所に何かを移動するとき、「もの」は最初の場所ではなく、別の場所でのこの操作の後にあることを私は理解しています。そして、memmoveではそのようには機能しません。私は正しいですか?

4

7 に答える 7

9

あなたは正しいです、それはそれをコピーします。ただし、とには違いがmemmoveあります。これは、バッファがオーバーラップしている場合を正しく処理できるため、これらの場合に推奨されますmemcpymemmove

ただし、追加のチェックがmemmove実行されるため、バッファが小さく、確実にオーバーラップしない場合のmemcpy方が適しています。

于 2010-12-18T20:56:02.123 に答える
6

memcpy()との違いはmemmove()memmove()送信元と宛先の間のエイリアシングに関係なく、常に安全に使用できることです。これは、memmove()データを最初に一時バッファにコピーし、次に宛先にコピーするかのようです。 memcpy()エイリアシングの保証はありません。意図したとおりに機能する場合もありますが、そうでない場合もあります。バッファがオーバーラップできないことがわかっている場合memcpy()は、問題なく、特定のライブラリで最適化を使用して、より高速にすることができますmemmove()。別のライブラリmemcpy()では、実際にはmemmove()

srcとdstをエイリアスにできないことがわかっている場合は、を使用しても安全memcpy()です。どちらが当てはまるかわからない場合は、を使用してくださいmemmove()

于 2010-12-18T20:59:37.760 に答える
5

この関数は、コピーされるメモリ領域がたまたまオーバーラップした場合、元のバッファが変更されていないため、コピーではなくなるため、そのように名付けられています。したがって、元のバッファは使用できないと見なす必要があります。memcpyではなくmemmoveを使用しているので、これが当てはまる可能性があります。したがって、名前付けには意味があります。意味的には、データをコピーするのではなく移動することになります。

于 2010-12-18T21:53:22.843 に答える
4

Memmove は、ソースから宛先にデータをコピーします。memcpyとは異なり、重複するメモリ領域での動作が保証されています。

于 2010-12-18T20:54:49.253 に答える
3

はい、memmove実際memcpyには重複するブロックを処理する機能があります。配列があり、最初にいくつかの新しいアイテムを挿入したい(またはいくつかのアイテムを削除したい)場合、同義的に、(既存または残りの)アイテムを前後に「移動」しているとしましょう-私は推測します、そしてその文脈では、名前は理にかなっています。

于 2010-12-18T20:54:02.073 に答える
3

はい、memmoveコピーの別のバリエーションです。元のバイトが操作前のバイトではなくなったという意味で、メモリを「移動」することはありません。特に、メモリが重複している場合を処理します。

これがどのように行われるかはアーキテクチャによって異なりますが、2つの異なる方法で行われるのを見てきました。

  • 2つのmemcpyタイプの操作で一時バッファーを使用します。また
  • オーバーラップタイプ(存在する場合)に応じて、最初のバイトから前方に、または最後のバイトから後方にコピーします。
于 2010-12-18T20:54:37.750 に答える
0

の名前についての質問に答えるにmemmove()は:この名前は、配列内の要素の範囲を配列内の別の範囲に移動するためのサポートを反映することを意図したものだと思います(たとえば、配列の先頭または内部に新しい要素のためのスペースを作るため) )。

他の回答が述べているように、オーバーラップするメモリ領域をサポートしていないためmemcpy()に利用できない最適化手法を使用できますが、サポートしています。memmove()memcpy()memmove()

コピーのパフォーマンスが重要なアプリケーションで作業している場合を除いて、デフォルトではmemmove()なく、引き続き使用することを検討してください。より良いパフォーマンスを提供できます(主に、より効果的にインライン化できるためです)が、アプリケーションによるCライブラリの誤った使用に関する議論からのLinuxカーネルでの実装に関するこの引用を覚えておいてください:memcpy()memcpy()memcpy()memcpy()

カーネルでは、使用する最適化されたx86 memcpyは実際にはmemmove()です。これは、パフォーマンスが非常に重要であると同時に、再現性と驚きの回避も重要であるためです(厳密に言えば、2つあります。高速で、オープンコード化されたコピーバージョンであると想定されています。「repmovs」バージョンは転送専用であり、重複する領域を処理しません)。

于 2010-12-19T08:41:41.730 に答える