現象對比
char s1[] = "hello world"; // 長度 12 (含隱式 \0)
char s2[11] = "hello world"; // 長度 11,無空間存 \0,strlen 讀取越界返回隨機值
內存佈局解析
s1: h e l l o w o r l d \0 ? ? ? ...
0 1 2 3 4 5 6 7 8 9 10 11
strlen 從 0 開始計數,遇到 \0 停止 → 11
s2: h e l l o w o r l d ? ? ? ...
0 1 2 3 4 5 6 7 8 9 10
無 \0,strlen 繼續讀取相鄰內存直到隨機遇到 0 → 不定值 (如 17, 24)
自定義 strlen 陷阱
size_t my_strlen(const char *s) {
int n = 0;
while (*s != '\0') { n++; s++; } // 正確:檢查字符值
return n;
}
// 錯誤寫法:while (*s != EOF) ... EOF 是 -1 (0xFF),字符無符號時永遠不等,導致無限循環或越界
最佳實踐
- 字符串字面量初始化時**不指定長度**或**長度 ≥ 字符串長度+1**。
- 手動構建字符串時**務必手動添加 \0**。
- 使用
strnlen(s, maxlen) 限制最大掃描長度,防止越界。