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

C語言 sizeof 與 memset/memcpy 陷阱深度解析

     編輯:關於C語言

sizeof 不是函數

  • 編譯期運算子,回傳 size_t(無號整數)。
  • sizeof int 或 sizeof(x) 皆合法,後者不求值表達式(不執行 x)。

經典陷阱:指標 vs 陣列

int a[100];
int *p = a;
printf("%zu %zu\n", sizeof(a), sizeof(p));  // 400  8 (64位系統)
  • sizeof(a) = 整個陣列大小 (100*4)。
  • sizeof(p) = 指標大小 (4/8),無法得知指向記憶體大小。

memset 陷阱

int a[100];
memset(a, 0, 100);   // 錯!第三參數是位元組數,僅清前 100 bytes (25 個 int)
memset(a, 0, sizeof(a)); // 正確:400 bytes
  • memset 按位元組填充,0 適用於整數/指標清零,但非 0 值不可用於整數陣列(會逐位元組填充,如 0x01010101)。
  • 浮點數/結構體含填充位元組時,memset 非 0 會產生非預期位模式。

memcpy 實現要點(面試必考)

void *memcpy(void *dest, const void *src, size_t n) {
    if (!dest || !src) return NULL;          // 空指標防護
    unsigned char *d = (unsigned char*)dest;
    const unsigned char *s = (const unsigned char*)src;
    // 處理記憶體重疊:向前/向後複製策略
    if (d < s) {
        while (n--) *d++ = *s++;             // 低址→高址,安全
    } else if (d > s) {
        d += n; s += n;
        while (n--) *--d = *--s;             // 高址→低址,避免覆蓋未讀資料
    }
    return dest;
}

關鍵考點

  1. 重疊處理:memmove 必須正確處理重疊,memcpy 標準未定義行為(但通常同向複製)。
  2. 對齊優化:實際庫實現會按字長(4/8/16/32 位元組)塊複製,尾部再補位元組。
  3. size_t 為無號:傳入負數會變巨大正數,導致緩衝區溢位,呼叫端必須保證 n >= 0。
  4. 回傳 dest:支援鏈式呼叫。

最佳實踐

  • 清零結構體:memset(&st, 0, sizeof(st)) 或 st = (typeof(st)){0} (C99 指定初始化器)。
  • 複製結構體:dst = src (編譯器生成最優複製) 優於 memcpy。
  • 動態陣列:配合 sizeof(*ptr) * count 而非硬編碼型別大小。
  • 嚴禁對含虛函數/虛基類的 C++ 物件用 memset/memcpy(破壞 vptr)。

掌握 sizeof 語義、memset 位元組語義與 memcpy 重疊處理,是寫出正確、高效、安全 C 記憶體操作代碼的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved