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