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

C 指標常見錯誤總結(三):指標與字串、NULL/NUL 混淆、字串傳遞與回傳陷阱

     編輯:關於C語言

C 指標常見錯誤總結(三):指標與字串、NULL/NUL 混淆、字串傳遞與回傳陷阱

本系列第三篇聚焦「指標與字串」交互產生的經典錯誤,涵蓋 NULL vs NUL、字串初始化四大陷阱、標準庫函式誤用、函式傳遞/回傳字串的記憶體管理、函式指標應用。

1. NULL vs NUL:一字之差,禍患無窮

  • NULL: 空指標常數,通常定義為 ((void*)0),用於指標比較/初始化。
  • NUL: 字元 '\0' (ASCII 0),字串結束標記。
  • 錯誤範例: if (str == NUL) 應為 if (str == NULL) 或 if (*str == '\0')。

2. 字串初始化四種形式與記憶體圖解

方式程式碼儲存區可修改?備註
字面常數char *s = "Hello";唯讀資料區否修改導致崩潰
陣列初始化char s[] = "Hello";堆疊/資料區是含結束符,長度 6
陣列逐字元char s[] = {'H','e','l','l','o','\0'};堆疊/資料區是手動加 \0
動態配置char *s = malloc(6); strcpy(s, "Hello");堆積是需 free(),長度含 \0

字串字面常數池 陣列初始化記憶體佈局 malloc+strcpy 動態配置

3. sizeof vs strlen 經典誤區

char s[10] = "Hello";
sizeof(s)  // 10 (編譯期陣列大小,含未使用空間)
strlen(s)  // 5   (執行期字串長度,遇 \0 停止)

sizeof 與 strlen 差異 標準輸入初始化 字串操作示意

4. 標準字串函式安全性陷阱

  • strcpy(dest, src):不檢查長度,src 過長導致緩衝區溢位。
  • strncpy(dest, src, n):若 src 長度 ≥ n,不自動補 \0,後續操作風險極大。
  • strcat(dest, src):同樣不檢查 dest 剩餘空間。
  • 建議: 使用 snprintf、strlcpy (BSD)、或手動檢查長度。

strcpy 覆蓋性 strncpy 不補 \0 strcpy 溢位 strcat 風險

5. 字串作為函式參數與回傳值

傳遞字串給函式

size_t stringLength(char *str) {
    size_t len = 0;
    while (*(str++)) len++;
    return len;
}

實際傳遞的是首字元位址,函式內可修改內容(除非參數為 const char*)。

回傳字串的三種合法來源

  1. 字面常數: return "Hello"; (靜態存活,唯讀)
  2. 動態記憶體: return malloc(...); (呼叫端須 free)
  3. 呼叫端提供緩衝區: void getStr(char *buf, size_t n); (最安全)

絕對禁止: 回傳區域陣列/字串指標(函式返回後堆疊框架銷毀,指標成懸空)。

命令列參數傳遞 函式指標與字串 回傳字串錯誤範例 正確回傳動態字串 呼叫端提供緩衝區

6. 函式指標操作字串:回呼模式

void process(const char *str, void (*callback)(const char *)) {
    // 處理邏輯...
    callback(str);  // 回呼
}

void printUpper(const char *s) {
    while (*s) putchar(toupper(*s++));
}

// 使用
process("hello", printUpper);

💡 核心原則: 「誰配置,誰釋放」;字串指標傳遞時明確標註 const;永遠假設輸入可能包含嵌入式 \0 或超長,邊界檢查不可省略。

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