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

C++ OJ 運行時錯誤(Runtime Error)排查:棧溢出與大數組陷阱

     編輯:程式設計綜合問答

錯誤現象

本地測試通過,提交 OJ 系統報 Runtime Error, code 11,典型的訪問未定義內存/棧溢出信號。

代碼隱患定位

#define Length 1600050
int trains[Length];   // 約 6.4 MB
int Seq[Length];      // 約 6.4 MB
// 兩個大數組共 ~12.8 MB,放在 main() 棧上,極易超過默認棧大小(通常 1-8 MB)

根本原因:棧溢出

  • 函數內部聲明的大型局部數組分鲁在**棧**上,棧空間有限(Linux 默認 8MB,Windows 1MB)。
  • 題目限制 n ≤ 1,600,000,兩個 int[1600050] 超過 12 MB,直接導致棧耗盡。

解決方案:改用堆內存

int *trains = new int[Length];
int *Seq = new int[Length];
// 使用完畢後釋放
delete[] trains;
delete[] Seq;

或使用 std::vector<int> trains(Length), Seq(Length); 自動管理內存,更安全現代。

其他潛在風險點

  1. 鏈表實現的 Pop 邏輯缺陷:Top->next; 這行語句無效果,應刪除;且未判斷 Top == Bottom 空棧情況。
  2. 演算法複雜度:雙重循環 O(n^2),n=1.6e6 時極慢,需優化為 O(n) 棧模擬(單次遍歷)。
  3. 輸入讀取:scanf 大量數據較慢,建議用快速 IO(fread/getchar_unlocked)。

優化後的核心邏輯(O(n))

// 單調棧模擬,一次遍歷
vector<int> seq;
Stack<int> s; // 用 vector 模擬棧,容量 m
int cur = 1; // 下一個入棧車廂編號
for (int target : targets) {
    while (cur <= target) {
        if (s.size() == m) { puts("No"); return; }
        s.push(cur++);
        seq.push_back(0); // push
    }
    if (s.empty() || s.top() != target) { puts("No"); return; }
    s.pop();
    seq.push_back(1); // pop
}
// 輸出 seq

將大數組移至堆、修正棧邏輯、優化演算法,即可通過 OJ 大數據測試。

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