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

C/C++ 字串結束符 \0 深度解析:內存佈局、常見陷阱與最佳實踐

     編輯:關於C語言

\0 的本質:不只是「結束標誌」

  • 類型:'\0' 為 char 類型(轉義字符),佔 1 字節;0 為 int 類型,通常佔 4 字節。
  • 值:ASCII 碼 0(0x00),非字符 '0'(ASCII 48,0x30)。
  • 作用:標識字串在內存中的邊界,C 標準庫函數(strlen、strcpy、printf("%s") 等)均依賴它判定結尾。

內存佈局實例

char str1[] = "Welcome!";  
// 內存:'W' 'e' 'l' 'c' 'o' 'm' 'e' '!' '\0'  (共 9 字節)
// sizeof(str1) = 9,strlen(str1) = 8

char str2[8] = "Welcome!";  
// 長度 8 不足以容納 8 字符 + \0 → \0 被截斷!
// 後果:strlen(str2) 讀越界,strcpy 導致緩衝區溢出

char str3[] = {'W','e','l','c','o','m','e','!'};  
// 無 \0,同樣危險
// 正確寫法:{'W','e','l','c','o','m','e','!','\0'} 或 char str3[9] = {..., '\0'}

三大經典陷阱

1. 緩衝區大小不足導致 \0 丟失

char buf[5];
strcpy(buf, "Hello");  // "Hello" 含 6 字節(含 \0),buf 只有 5 → 溢出
// 正確:char buf[6]; 或 strncpy(buf, "Hello", 5), buf[5] = '\0';

2. 字面量指針指向唯讀區

char *p = "hello";
p[0] = 'H';  // 未定義行為,通常段錯誤
// 正確:char p[] = "hello";  // 分配在棧上,可修改

3. 手動拼接字串忘記補 \0

char dest[20] = "Hello";
char *src = "World";
while (*src) *dest++ = *src++;  // 循環結束時 dest 指向末尾,但未寫 \0
*dest = '\0';  // 必須手動補上

\0 vs NULL:一字節與指針的區別

特性'\0' (NUL)NULL
類型char (整數 0)void* (空指針,通常 (void*)0)
用途字串結束標誌指針無效標誌
大小1 字節4/8 字節(指針寬度)
可互換?不可不可

char *p = '\0'; 編譯警告(整數轉指針);char c = NULL; 編譯警告(指針轉整數)。

最佳實踐清單

  1. 優先用字面量初始化:char s[] = "text"; 編譯器自動補 \0 且計算正確大小。
  2. 手動構建字串時:分配 strlen(src) + 1 空間,memcpy 後顯式寫 dest[len] = '\0'。
  3. 使用安全函數族:strncpy、snprintf、strlcpy(BSD),並在調用後手動確保終止符。
  4. 調試時檢查 \0:printf("len=%zu, sizeof=%zu\\n", strlen(s), sizeof(s));若 sizeof == strlen,極大概率缺 \0。
  5. 嵌入式/網絡協議:若協議使用「長度前綴」而非 \0 結尾,務必在轉換層正確處理,避免二進制數據中含 0x00 被誤判為結尾。

總結

\0 是 C 風格字串的靈魂:佔 1 字節、值為 0、類型為 char。它不計入 strlen,但計入 sizeof 與實際內存佔用。所有字串操作的安全性最終都建立在「正確放置 \0」之上。牢記:沒有 \0 的 char 數組,不是字串,只是字節序列。

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