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

memcpy 實現完全指南:從原型推導到健壯實現、重疊處理與面試避坑

     編輯:關於C語言

需求分析與原型確定

  1. 拷貝任意類型數據 → void*
  2. 源數據只讀 → const void*
  3. 需指定拷貝字節數 → size_t n
  4. 返回目標地址便於鏈式調用 → void*
void *memcpy(void *dest, const void *src, size_t n);

錯誤處理考量

  • 空指針檢查:dest==NULL || src==NULL → 返回 NULL
  • 計數異常:n==0 → 直接返回 dest (標準行為)
  • 目標空間足夠:**無法在函數內保證**,屬調用者責任
  • 內存重疊:memcpy **未定義行為**,重疊用 memmove

逐字節實現 (教學版)

void *memcpy(void *dest, const void *src, size_t n) {
    if (!dest || !src) return NULL;
    char *d = (char*)dest;
    const char *s = (const char*)src;
    // 保存原始 dest 用於返回
    void *ret = dest;
    while (n--) *d++ = *s++;
    return ret;
}

常見面試錯誤與修正

生產級優化策略

  1. 字對齊拷貝:按 sizeof(long) 或 SIMD (SSE/AVX/NEON) 批量拷貝
  2. 方向優化:dest < src 正向,dest > src 逆向 (避免重疊時覆蓋源數據,雖 memcpy 不保證)
  3. 小塊優化:n < 16 用展開循環

標準庫實現參考 (glibc 簡化)

void *memcpy(void *dest, const void *src, size_t n) {
    if (!n) return dest;
    // 對齊處理、大塊 vectorized 拷貝、尾部字節拷貝...
    return dest;
}

面試回答要點

  1. 先給標準原型,說明各參數含義
  2. 列出錯誤處理:空指針、零長度
  3. 給出正確逐字節實現 (保存返回值、轉 char*)
  4. 補充:重疊用 memmove,優化思路 (對齊、SIMD、方向)
  5. 強調 restrict 關鍵字 (C99) 告訴編譯器不重疊
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤代碼問題修正
return dest; (循環後)dest 已遞增指向末尾保存 void *ret = dest; 循環前
while(n--) *dest++ = *src++;void* 不能算術運算轉 char* 後操作
if (n <= 0) return NULL;size_t 無符號,n==0 合法if (n == 0) return dest;