原始碼存在**硬編碼位移**、**錯誤重疊判斷**、**返回值錯誤**三大缺陷。本文提供標準合規、生產級的 `memmove` 實現。
// 原始碼問題:
void *my_memmove(void *p1, void *p2, size_t count) {
char *dest = (char *)p1;
char *src = (char *)p2;
dest = dest + 16; // 硬編碼偏移!破壞通用性
src = src + 8; // 硬編碼偏移!
if ((src < dest) && (dest < src + count)) { ... }
return p2; // 應返回 p1 (dest 起始位址)
}
#include#include void *my_memmove(void *dest, const void *src, size_t count) { assert(dest && src); char *d = (char *)dest; const char *s = (const char *)src; void *ret = dest; if (d == s || count == 0) return ret; // 正確重疊判斷:dest 在 src 之後,且距離小於 count if (d > s && d < s + count) { // 重疊:從後向前複製 d += count; s += count; while (count--) { *--d = *--s; } } else { // 不重疊或 dest 在 src 之前:正向複製 while (count--) { *d++ = *s++; } } return ret; }
int main() {
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int len = sizeof(arr)/sizeof(arr[0]);
// 測試 1:前移覆蓋 (src 在 dest 後,正向安全)
// 將 arr[2..5] 複製到 arr[0..3] → 結果: 3,4,5,6,5,6,7,8,9,10
my_memmove(arr, arr+2, 4*sizeof(int));
for (int i=0;i
執行結果
3 4 5 6 5 6 7 8 9 10
1 2 1 2 3 4 7 8 9 10
關鍵測試案例對比表
場景 src dest count 方向 原始碼結果 修正版結果
前移不重疊 arr+5 arr 3*sizeof(int) 正向 錯 (硬編碼偏移) ✓
後移重疊 arr arr+2 4*sizeof(int) 反向 錯 (判斷邏輯+偏移) ✓
同位址 arr arr 10 無 錯 (偏移後不等) ✓ (快速返回)
count=0 任意 任意 0 無 錯 (進入迴圈) ✓ (快速返回)
總結
`memmove` 核心在於**無硬編碼偏移**、**精準重疊判斷 `d > s && d < s + count`**、**正確返回 `dest`**。原始碼硬編碼 `+16/+8` 徹底破壞通用性,返回 `p2` 違反標準語義。生產代碼直接使用 `memmove` 或編譯器內建 `__builtin_memmove`。