sizeof 是運算符 (編譯期),strlen 是函數 (運行期) —— 這是本質區別。本文通過 8 組對比案例,徹底講清兩者在數組、指針、動態內存、結構體等場景下的行為差異。
| 特性 | sizeof | strlen |
|---|---|---|
| 性質 | 運算符 (關鍵字) | 函數 (庫函數) |
| 計算時機 | **編譯期** | **運行期** |
| 參數類型 | 類型/變量/表達式/函數調用 | const char* (以 \0 結尾) |
| 返回類型 | size_t | size_t |
| 語義 | **佔用內存字節數** (含填充/對齊) | **字符串長度** (不含 \0) |
| 數組參數 | 不退化,得整個數組大小 | 退化為指針,得字符串長度 |
| 指針參數 | 得指針本身大小 (4/8) | 得指向字符串長度 |
| 動態內存 | 無法得知分配大小 | 能得知字符串長度 |
| 結構體 | 含對齊填充的總大小 | 不適用 (非字符串) |
char str[20] = "0123456789"; strlen(str); // 10 sizeof(str); // 20 (數組定義大小,與內容無關)
char *p = "0123456789"; sizeof(p); // 4/8 (指針大小) sizeof(*p); // 1 (char 大小) strlen(p); // 10
void foo(char arr[8]) { // 等價 char *arr
sizeof(arr); // 4/8 (指針大小!)
strlen(arr); // 正常工作
}
對策: 同時傳遞長度參數,或結構體封裝 {char *p; size_t len;}。
char *p = malloc(100); sizeof(p); // 4/8 (指針) strlen(p); // 不定值 (未初始化內容) strcpy(p, "hello"); strlen(p); // 5
struct { char c; int i; } s;
sizeof(s); // 8 (非 5!編譯器插入 3 字節填充對齊 int)
sizeof(int); // ✅ sizeof int; // ✅ (僅變量可省略括號) sizeof (int); // ✅
void fun(unsigned char *p, int len) {
unsigned char *buf = malloc(len + 1);
memcpy(buf, p, len); // 必須外部傳長度
}
char str2[] = "absde"; sizeof=6 (5字符+\0)
char str3[8] = {'a'}; sizeof=8 (定義大小)
char ss[] = "0123456789"; sizeof=11 (10字符+\0)
sizeofstrlensizeof 失效malloc_usable_size (GNU 擴展)%zu (C99),別用 %d/%u/%ld