memmoveとmemcpyの違いとメモリの重複の問題



Difference Between Memmove



違い:

memcpyとmemmove()はどちらもC言語のライブラリ関数です。ヘッダーファイルstring.hでは、特定の長さのメモリの内容をコピーする機能があります。プロトタイプは次のとおりです。



void *memcpy(void *dst, const void *src, size_t count) void *memmove(void *dst, const void *src, size_t count)


それらの機能は同じですが、唯一の違いは、メモリがローカルでオーバーラップする場合、memmoveはコピー結果が正しいことを保証し、memcpyは正しいコピー結果を保証しないことです。
1つはmemcpy関数です

Memcpyプロトタイプ:



void *memcpy(void *dest, const void *src, size_t n)


説明:
memcpy()関数は、srcメモリからdestメモリ領域にnバイトをコピーしますが、ソースメモリ領域と宛先メモリ領域をオーバーラップさせることはできません。
戻り値:
memcpy()関数は、destへのポインターを返します。
2.memmove機能
memmoveプロトタイプ:

void *memmove(void *dest, const void *src, size_t n)


説明 :memmove()関数は、srcメモリからdestメモリ領域にnバイトをコピーしますが、ソースメモリと宛先メモリが重複する可能性があります。
戻り値 :memmove関数はdestへのポインタを返します。

上記の説明からわかるように、2つの違いは、重複する領域を処理する場合、memmoveは対応するコピーを正しく完了することができますが、memcpyはできないことです。



メモリの上書きには2つのケースがあります。

最初に、2つの関数memcpy()とmemmove()の実装を見てください。

void* my_memcpy(void* dst, const void* src, size_t n) { char *tmp = (char*)dst char *s_src = (char*)src while(n--) { *tmp++ = *s_src++ } return dst }


実装から、memcpy()がsrcの内容をメモリの左側からdestのメモリにバイト単位でコピーしていることがわかります。この実装方法により、図の2番目のメモリオーバーラップ状況では、最後の2バイトのコピー値が明らかに元の値ではなく、新しい値がsrcの最初の2バイトになります。

最初のメモリ上書き状況では、memcpyのこのコピー方法が可能です。

Memmoveは、2番目のメモリカバレッジ状況のmemcpyを改善します。改善されたコードは次のとおりです。

void* my_memmove(void* dst, const void* src, size_t n) { char* s_dst char* s_src s_dst = (char*)dst s_src = (char*)src If(s_dst>s_src && (s_src+n>s_dst)) {//-------------------------The second case of memory overwriting. s_dst = s_dst+n-1 s_src = s_src+n-1 while(n--) { *s_dst-- = *s_src-- } }else { while(n--) { *s_dst++ = *s_src++ } } return dst }


2番目のメモリ上書きの状況では、memcpyはエラーを起こしますが、memmoveは正常に機能します。

例:

int main () { char c1[20] = {0} snprintf(c1, sizeof(c1), 'hello world') printf('original str : %s',c1) printf(' ') memcpy(c1+3, c1, 9) printf('memcpy result : %s',c1) printf(' ') snprintf(c1, sizeof(c1), 'hello world') memmove(c1+3, c1, 9) printf('memmove result : %s',c1) printf(' ') return 0 }

出力は次のとおりです。

original str : hello world memcpy result: helhellellol // completely messed up memmove result: helhello wor // Correctly handle the memory overlap problem

参照: https://blog.csdn.net/li_ning_/article/details/51418400

https://blog.csdn.net/weixin_41883223/article/details/84888719