首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

memcpy 實現核心要點:重疊處理、const 正確性與返回值利用

     編輯:關於C語言

標準級實現

void* memcpy(void* dest, const void* src, size_t count)
{
    // 1. src 加 const:承諾不修改源數據
    char* pdest = (char*)dest;
    const char* psrc = (const char*)src;

    // 2. 保存原始 dest 用於返回,支持鏈式調用
    void* ret = dest;

    // 3. 重疊檢測:dest 在 src 區間內,且 dest > src(向上重疊)
    if (pdest > psrc && pdest < psrc + count) {
        // 從尾部向前複製,避免覆蓋未讀數據
        pdest += count - 1;
        psrc  += count - 1;
        while (count--) *pdest-- = *psrc--;
    } else {
        // 正常情況:從頭向後複製
        while (count--) *pdest++ = *psrc++;
    }
    return ret; // 5. 返回原始 dest
}

五大關鍵點解析

  1. const 正確性:const void* src 防止誤寫源數據,允許傳入字符串常量、只讀內存。
  2. 字節級操作:轉為 char* 逐字節複製,符合 C 標準「字符類型可訪問任意對象表示」。
  3. 重疊安全:
     - dest < src:向前複製安全(如 memcpy(buf, buf+2, 10))。
     - src 且重疊:必須向後複製(如 memcpy(buf+2, buf, 10))。
     - 標準庫 memmove 保證處理所有重疊;memcpy 行為未定義,**但優質實現通常內建重疊檢測**。
  4. 保存返回值:ret 保存原始 dest,因複製過程中 pdest 已移動。支持 strcat(memcpy(dst, src, n), tail) 等鏈式調用。
  5. 性能優化(生產級):
     - 位對齊檢測 → 以 uintptr_t/uint64_t 塊複製(8/16 字節)。
     - SIMD 指令集(SSE/AVX/NEON)向量化。
     - 預取指令、非時序存儲。
     - 小塊專用展開、大塊頁對齊優化。
     面試手寫版掌握邏輯正確性即可,工程中直接用編譯器內建/庫函數。

memcpy vs memmove vs strcpy

函數重疊行為終止條件返回值典型用途
memcpy未定義(實現常處理)計數 countdest二進制塊複製,已知長度
memmove保證安全計數 countdest可能重疊的塊複製
strcpy未定義遇 '\0'destC 字符串複製
strncpy未定義計數 或 '\0'dest固定寬度字符串(不保證以 '\0' 結尾)

面試/考試常見陷阱題

// 錯誤:未處理重疊,且未返回 dest
void* bad_memcpy(void* d, const void* s, size_t n) {
    char* pd = (char*)d; const char* ps = (const char*)s;
    while (n--) *pd++ = *ps++;
    // 缺 return d;
}

// 錯誤:重疊判斷條件寫反
if (pdest < psrc && pdest + count > psrc) // 應為 pdest > psrc && pdest < psrc + count

// 錯誤:直接用 int* 複製,違反嚴格別名規則,可能導致誤優化
while (count >= 4) { *(int*)pdest = *(int*)psrc; ... }
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved