for (vector::iterator it = stcStruct.vecInfo.begin();
it != stcStruct.vecInfo.end(); ++it) // 這裡觸發 Debug 斷言失敗
{ ... }
明明同一 vector,卻報「迭代器不相容」。耗時 4 小時排查,最終在 STL 原始碼中找到真相。
vector::iterator 比 vector::iterator 。erase(it) 後未更新 it = vec.erase(it),導致迭代器失效。vector 比較。ZeroMemory 摧毀了 vector 內部指標typedef struct _STRUCT {
vector vecInfo;
} STRUCT;
STRUCT stcStruct;
// ... 某處構造函數中 ...
ZeroMemory(&stcStruct, sizeof(STRUCT)); // 禍根!
vector 內部持有 _Myproxy 指標,指向 _Container_proxy 物件,維護迭代器雙向鏈表(支援迭代器失效檢查)。_Myproxy 在 vector 建構時初始化,非 POD,不能用 memset/ZeroMemory 清零。ZeroMemory 將 _Myproxy 置 0 → 迭代器 _Getcont() 回傳 0 → _Compat 判定「迭代器不相容」觸發斷言。push_back、size 等操作表面正常(動態分配記憶體),唯獨遍歷(begin/end 比較)失敗,極具迷惑性。void _Compat(const _Myiter& _Right) const {
if (this->_Getcont() == 0 || this->_Getcont() != _Right._Getcont()) {
_DEBUG_ERROR("vector iterators incompatible");
_SCL_SECURE_INVALID_ARGUMENT;
}
}
const _Container_base12* _Getcont() const {
return (_Myproxy == 0 ? 0 : _Myproxy->_Mycont);
}
memset/ZeroMemory。STRUCT stcStruct; 即可)。stcStruct = STRUCT();(C++11 移動語意)、或提供 reset() 成員函式。vector、string、智慧指標、虛函式、自定建構/解構函式的類別皆為非 POD。memcpy 複製含 vector 的結構體 → 雙重釋放、迭代器指向舊 proxy。realloc 擴充含 C++ 物件的記憶體區塊 → 物件未正確建構/解構。ZeroMemory 是 C 時代遺留習慣,C++ 中對非 POD 類別是**毀滅性打擊**。本案例中 vector 表面功能正常、唯獨迭代器遍歷崩潰,完美詮釋了「未定義行為」的隱蔽殺傷力。請時刻保持對 C++ 物件模型的敬畏。