Debug 模式:觸發中斷點,報告「存取違規 / 迭代器失效 / 堆積損毀」。
常見原因排查
- 類別缺少正確的拷貝/移動語意:
若 `POINT3D` 內含原始指標、陣列、資源句柄,預設淺拷貝會導致雙重釋放或懸空指標。
對策:實作「三大法則/五大法則」(複製建構子、複製指派、解構子、移動建構子、移動指派),或改用智慧指標/標準容器成員。
- Debug 迭代器偵錯機制更嚴格:
MSVC Debug 模式啟用 `_ITERATOR_DEBUG_LEVEL=2`,會檢查迭代器失效、越界、容器修改中迭代等。Release 不檢查,故「跑得過」不代表正確。
- 記憶體越界寫入破壞 vector 內部結構:
程式其他處(緩衝區溢位、野指標)破壞了 vector 的 `_Myproxy` / `_Mypair` 等內部欄位,導致 push_back 時檢查失敗。
診斷步驟
- 檢查 `POINT3D` 定義:是否有指標成員?是否遵循 RAII?
- 在 push_back 前後加入斷點,觀察 `pts.size()`, `pts.capacity()`, `pts._Myfirst` 位址是否合理。
- 啟用
_CRTDBG_MAP_ALLOC 與 _CrtDumpMemoryLeaks() 偵測堆積損毀。
- 使用 Application Verifier 或 AddressSanitizer (ASan) 定位記憶體錯誤來源。
最小可重現範例
struct POINT3D {
double x, y, z;
// 若有指標:int* data; -> 需自訂拷貝/移動
};
vector pts; // 全域
void test() {
POINT3D p{1.0, 2.0, 3.0};
pts.push_back(p); // Debug 斷在此
}
若 `POINT3D` 只有 POD 型別成員,上述程式碼在 Debug/Release 皆應正常。若仍報錯,極大機率是其他程式碼破壞了全域 vector 的記憶體。
總結
Debug 觸發、Release 正常,通常意味著程式存在潛在記憶體錯誤(如淺拷貝雙重釋放、緩衝區溢位),Debug 運行時檢查恰好捕捉到了。請優先檢查自訂類別的資源管理規則,並用 Sanitizer 定位破壞源頭。