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

C 陣列下標越界不報錯:未定義行為、編譯器不檢查、執行時才可能崩潰

     編輯:程式設計疑難解答

代碼

void strtol(char s[]) {
    int i = 0;
    while (s[i++]);
    while (i >= 0)
        s[i--] = s[i]; // i 會變 -1,s[-1] 越界
}

為何編譯通過、運行不崩潰?

  • C 標準不要求編譯期檢查陣列邊界,性能優先。
  • 執行期也不保證崩潰:越界訪問屬**未定義行為 (UB)**,可能:
    • 讀/寫相鄰變數(如上例修改了 i 自身或其他局部變數)。
    • 觸及保護頁 → 段錯誤。
    • 看似正常執行(最危險)。
  • s[i--] = s[i] 先取值 s[i] 再遞減 i,實際執行 s[i] = s[i](無操作),再 i--。但 i 從字串長度遞減至 -1,循環條件 i >= 0 滿足,進入迴圈體時 i = -1,寫入 s[-1] 破壞棧上相鄰數據。

防護工具

  • 編譯 -fsanitize=address -fno-omit-frame-pointer (GCC/Clang) → 運行時精準報告越界位置。
  • MSVC /RTC1 /GS 執行期檢查 + 棧保護。
  • 靜態分析 cppcheck --enable=all、Clang-Tidy。

結論

**不報錯 ≠ 正確**。C 將邊界檢查責任留給程式設計師,務必自行保證索引合法。

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