運算式堆疊 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 被竄改。
-fstack-protector-strong、Clang -fsanitize=address (ASan)valgrind --tool=memcheck 偵測非法存取| 方案 | 優點 | 缺點 |
|---|---|---|
std::vector + at() | 邊界檢查、自動擴容 | 輕微效能開銷 |
std::array | 固定大小、可選邊界檢查 | 編譯期需知大小 |
| 自訂安全陣列包裝類 | 完全控制行為 | 開發成本 |
陣列越界是 C/C++ 最隱蔽且破壞力強的 Bug 來源之一。現代工具鏈(ASan、UBSan)能在執行期精準定位,建議所有專案納入 CI 流程強制啟用。