錯誤代碼片段
char giver[9][13], receiver[9][13], person; // 錯誤:person 聲明為單個 char
// ...
fscanf(input_file, "%s", &person); // 以 %s 讀取字符串寫入單 char 地址 → 緩衝區溢出
printf("%s\n", &person); // 讀取無效內存
Bus Error 10 解析
- Bus Error (SIGBUS):CPU 檢測到內存總線錯誤,通常因**未對齊訪問**或**訪問不存在物理地址**。
- 此處 `char person` 僅佔 1 字節,`fscanf("%s", &person)` 會寫入字符串(含結束符 `\0`),至少 2 字節,覆蓋相鄰棧內存(如返回地址、幀指針),導致棧幀損壞,函數返回時跳轉到非法地址觸發 Bus Error。
- 輸入 `dave` (4字節+1) 覆蓋範圍較大必現錯誤;短名字可能僅覆蓋無關變量,運行時不立即崩潰,極具迷惑性。
修正代碼
char person[13]; // 改為字符數組,足夠存儲最長名字+結束符
// ...
fscanf(input_file, "%12s", person); // 限制寬度防止溢出
printf("%s\n", person); // 直接傳遞數組名(首地址)
良好習慣
- **永遠不用 `%s` 無寬度限制**,改用 `%12s` (緩衝區大小-1)。
- 啟用編譯器緩衝區溢出保護:`-fstack-protector-strong` (GCC) / `/GS` (MSVC)。
- 使用 `fgets` 讀整行,再 `sscanf` 解析,更安全可控。
- 靜態分析工具 (Cppcheck, Clang Static Analyzer) 可自動檢測此類缺陷。