首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

陣列越界導致變數被竄改:堆疊佈局與未定義行為深度剖析

     編輯:關於C語言

案例現場

運算式堆疊 st[MAXSIZE] 與變數 top 在堆疊上相鄰,因條件判斷錯誤導致 st[-1] 寫入,實際修改了 top 的值。

錯誤程式碼片段

int st[MAXSIZE] = {0};
int top = -1;

// 錯誤:未檢查 top == -1 直接呼叫 isMax(scr[i], st[top])
if (isMax(scr[i], st[top])) { ... }  // top=-1 時存取 st[-1]

記憶體佈局示意

高地址
+----------------+
|   其他區域變數  |
+----------------+
|      top       |  ← 4 bytes
+----------------+
| st[0] ~ st[99] |  ← 400 bytes
+----------------+
低地址

st[-1] 正好落在 top 位置,寫入運算子字元碼(如 '*'=42)導致 top 被竄改。

根本原因

  • C 語言不檢查陣列邊界
  • 區域變數在堆疊上連續排列,越界寫入會破壞相鄰變數
  • 函數呼叫參數傳遞、暫存器保存等可能加劇堆疊佈局變化

除錯技巧

  1. 啟用編譯器邊界檢查:GCC -fstack-protector-strong、Clang -fsanitize=address (ASan)
  2. 使用 valgrind --tool=memcheck 偵測非法存取
  3. 靜態分析:Cppcheck、Clang Static Analyzer
  4. 防御性程式設計:所有陣列存取前檢查索引範圍

安全替代方案

方案優點缺點
std::vector + at()邊界檢查、自動擴容輕微效能開銷
std::array固定大小、可選邊界檢查編譯期需知大小
自訂安全陣列包裝類完全控制行為開發成本

總結

陣列越界是 C/C++ 最隱蔽且破壞力強的 Bug 來源之一。現代工具鏈(ASan、UBSan)能在執行期精準定位,建議所有專案納入 CI 流程強制啟用。

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