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

C++ 陣列越界不報錯?未定義行為深度解析

     編輯:程式設計綜合問答

現象

程式中 dp[j-1] 當 j==0 時存取 dp[-1],屬於陣列越界,但程式仍能執行並輸出結果,未崩潰或報錯。

原因

C/C++ 不執行陣列邊界檢查。越界存取屬於「未定義行為」(Undefined Behavior, UB):

  • 可能讀到相鄰記憶體的殘留值,程式看似正常。
  • 可能破壞其他變數,導致難以重現的錯誤。
  • 可能觸發段錯誤(存取受保護頁面)。
  • 編譯器優化時可能假設不會越界,產生不可預期的機器碼。

為何此例未崩潰

dp 為全域/靜態陣列,位於 .bss 段。dp[-1] 正好落在相鄰變數 str 陣列尾端,讀到的是 str 的資料,剛好不影響邏輯,故程式「碰巧」跑通。

最佳實務

  1. 啟用編譯器警告:-Wall -Wextra -Warray-bounds (GCC/Clang) 或 /Wall (MSVC)。
  2. 使用安全容器:C++ 改用 std::vector、std::array,配合 .at() 執行期檢查。
  3. 靜態分析工具:Cppcheck、Clang Static Analyzer、PVS-Studio。
  4. 執行期檢測:AddressSanitizer (-fsanitize=address)、Valgrind。

程式碼修正

for (int j = 0; j <= i; j++) {
    if (str[j] == str[i] && judge(j, i)) {
        int prev = (j == 0) ? 0 : dp[j - 1]; // 邊界保護
        dp[i] = min(dp[i], prev + 1);
    }
}

總結

「能跑」不代表「正確」。C/C++ 將陣列邊界檢查留給程式設計師,務必養成防禦性程式習慣,善用工具提早發現 UB。

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