2012-01-28 2 views
9

IはMEMMOVE()を使用し、約2つの疑いを持たどのように使用すると、Cでmemmoveを使用して良いですか?

好ましい使用は、この機能の代わりに使用する別の関数である(すなわち、A自身の機能を作成)
  • ?私は正しく理解しているかどうかはわかりません。
  • 関数のシグネチャはボイド* MEMMOVE(ボイド* DEST、CONSTボイド*のSRC、size_tのN)あります。私は単純な配列を持っている場合arr [N]、どのように私はそれを呼び出された関数に入れることができますか? arr [N]または& arr [N]?違いは、配列が初期サイズで宣言されているか、ポインタのように宣言されているかどうかです。私はこの疑念を持っています。なぜなら、両方が使用されている多くの例を見たからです。

私は良い方法で私の疑問を説明したいと考えています。

編集:私は、配列から要素を削除する必要があり、その後、私は左に削除された1の次の要素をシフトします。

+1

関連性http://stackoverflow.com/questions/1960991/which-one-to-use-memmove-or-memcpy-when-buffers-dont-overlap –

答えて

13
  1. memmoveは速いかもしれないが、それはおそらく(通常、現在のアーキテクチャ上で可能な限り最も効率的な方法で周りのものを移動するために巧妙に作成されたアセンブリでコーディングされています)の周りにデータをコピーするための独自の機能よりも遅くなることはありません。
  2. それはあなたがその配列で何をしたいかによって決まります...もしそのコンテンツを他の配列にコピーしたいのであればarrで十分です(そして、lengthパラメータとしてsizeof(*arr)*NをNとしてコピー)。

ところで、送信元と送信先とコピーが重複していない場合は、memcpyが高速になる可能性があります。

配列から要素を削除して、同じ配列の要素を左に移動したいとします。

int arr[N]; 
/* ... */ 
/* Let's say you want to remove the element i (error checking on i omitted) */ 
memmove(arr+i, arr+i+1, (N-i-1)*sizeof(*arr)); 
/* or, if you prefer array indexing over pointer arithmetics: */ 
memmove(&arr[i], &arr[i+1], (N-i-1)*sizeof(*arr)); 

sizeof(*arr)「は、配列の要素のサイズを取得する」を意味する)

+0

私は配列から要素を削除し、要素を左に移動したい同じ配列。 – Kyrol

+1

@Kyrol:更新された回答。 –

+2

重複していないデータの方が 'memcpy'が速いことに注意してください。 'memcpy'を使っても、単一の配列オブジェクト内の要素をシフトするのではなく、異なるオブジェクト間でコピーしていることを文書化するのに役立ちます。 –

0

好ましい使用は、他の機能の代わりに使用すると、この関数である(すなわち、Aが自身の機能を作成した)

それは、「独自の関数を作成した」よりも高速です。

関数のシグネチャは、void * memmove(void * dest、const void * src、size_t n)です。私が単純な配列arr [N]を持っていれば、それを呼び出された関数にどのように入れることができますか? arr [N]または& arr [N]

ちょうどarr

+0

私の2番目の質問について何を理解していないのですか?私はもっ​​と良く説明しようとする。たとえば、 – Kyrol

4

memmoveは重複することができる宛先とソースアレイ以外memcpyようなものです。 memcpy

あなたは地域の実装はいくつかの追加の最適化を実行することを可能にする重複しないことを約束します。だからmemcpymemmoveより速くなる可能性があります。

memmove関数は、宛先引数void *とソース引数const void *をとります。これは、ポインタ型に変換されるため、配列型のdestination引数とsource引数を持つ関数を呼び出すことができることを意味します。また、非修飾オブジェクトポインタ型をvoid *またはconst void *に割り当てることができるので、関数を呼び出すときにキャストは必要ありません。

char src[1024] = {0}; 
char dst[1024]; 

memmove(dst, src, sizeof dst); 
/* src and dst don't overlap you should choose memcpy instead */ 
memcpy(dst, src, sizeof dst); 

は、今では、独自の機能をコーディングするよりも、memcpyまたはmemmoveを使用する方が良いでしょう。たとえば、glibcでは、MCUの命令セットとコピーするサイズによっては、memcpyという高速インラインアセンブリバージョンを使用して、memcpyをコンパイラに置き換えることができます。

+0

+1です。ありがとう。 – Kyrol

+0

srcとdstが同じ配列である場合??なぜなら、要素を削除して、削除した要素の後に他の要素を残さなければならないかどうかという疑念があるからです。 – Kyrol

+0

@Kyrol:まだ 'char src [1024] = {0}'の例です。 'memcpy(src、src + 512、512);'同じオブジェクトですが、リージョンは重複しません。しかし、 'memcpy(src + 256、src + 512,512);'領域が重複しています。そうではありません。代わりに 'memmove'を使います。 – ouah

関連する問題