首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言字符串長度計算錯誤排查:指針類型不匹配與 gets() 危險性

     編輯:程式設計綜合問答

問題代碼

int slen(int *p) { // 參數類型錯誤
    int l=0;
    for(; *p!='\0'; p++) l++;
    return l;
}

int main() {
    char s[1000];
    int *p = s; // char* 強制賦值給 int*,類型不匹配
    gets(s);    // 危險:無緩衝區溢出保護
    printf("%d", slen(p));
}

核心錯誤分析

  1. 指針類型錯誤:slen 參數為 int*,但傳入 char*。
    在 32/64 位系統上 sizeof(int) != sizeof(char),指針算術 p++ 會按 sizeof(int) (4/8 字節) 遞增,導致每次跳過 3/7 個字符,讀取到的值非預期字符,最終讀到垃圾內存中的 0 終止,長度計算完全錯誤(常見輸出 256 等隨機值)。
  2. 使用 `gets()`:C11 已移除,無長度檢查,極易造成緩衝區溢出漏洞,嚴禁使用。
  3. 無需指針變量:直接傳遞數組名 s(退化為 char*)即可。

正確寫法

#include <stdio.h>
#include <string.h> // 標準庫 strlen

// 方式 1:使用標準庫(推薦)
int main() {
    char s[1000];
    printf("請輸入字符串:");
    fgets(s, sizeof(s), stdin); // 安全讀取,含換行符
    s[strcspn(s, "\n")] = '\0'; // 移除換行
    printf("長度:%zu\n", strlen(s));
    return 0;
}

// 方式 2:手寫教學版(正確指針類型)
size_t my_strlen(const char *p) {
    size_t len = 0;
    while (*p++) len++;
    return len;
}

建議

  • 生產代碼直接用 strlen / strnlen。
  • 輸入永遠用 fgets / getline / scanf("%999s", s) 限制長度。
  • 指針類型必須與指向對象類型嚴格匹配,開啟編譯器警告(-Wall -Wextra / /W4)可自動捕獲此類錯誤。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved