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

C 語言數組越界不報錯?解析未定義行為與必現崩潰示例

     編輯:程式設計疑難解答

C 標準規定數組越界屬於**未定義行為 (UB)**:編譯器不保證報錯,運行時可能正常、數據悄悄損壞、延遲崩潰、甚至看起來正確。這是 C 語言「信任程序員」設計哲學的體現。

為什麼有時不報錯?

  • 越界寫入落在同一棧幀內其他變量區域,覆蓋局部變量/保存的幀指針/返回地址
  • 釋放構建 (Release) 移除邊界檢查,調試構建 (Debug) 某些編譯器 (MSVC `/RTCs`) 會插入運行時檢查
  • 訪問合法映射的內存頁,硬件無頁錯誤中斷

必現崩潰示例:無限越界寫入

#include 
#include 

int main() {
    int a[10];
    int i = 0;
    while (1) {
        a[i++] = i;  // 持續向高地址寫入
        // 終將覆蓋棧守護頁或關鍵控制數據,觸發段錯誤/棧溢出
    }
    return 0;
}

運行結果:`Segmentation fault (core dumped)` 或 `Stack overflow`,通常在幾萬次循環後發生。

更隱蔽的災難:覆蓋返回地址

void victim() {
    char buf[8];
    // 攻擊者構造輸入覆蓋 buf 後的返回地址
    gets(buf);  // 危險函數,無長度檢查
    // 返回時跳轉到攻擊者指定地址 → 代碼執行漏洞
}

int main() {
    victim();
    return 0;
}

防範最佳實踐

層級措施
編碼規範禁用 `gets`/`strcpy`/`sprintf`,改用 `fgets`/`strncpy`/`snprintf`/`memcpy_s`
編譯器保護開啟 `-fstack-protector-strong` (GCC/Clang)、`/GS` (MSVC) 棧保護
運行時檢查AddressSanitizer (`-fsanitize=address`) 開發/測試階段必開
靜態分析Cppcheck、Clang Static Analyzer、Coverity 掃描越界風險
現代 C++用 `std::vector`/`std::array`/`std::string` 替代裸數組,配合 `.at()` 邊界檢查
「不報錯」不代表「沒事」。數組越界是 C/C++ 最大安全隱患來源,務必用工具鏈 + 規範雙重防線。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved