程序運行正常,輸出正確,但在退出時觸發 0xC0000005 訪問沖突,地址 0xfeeefef6(MSVC 虛擬內存標記已釋放內存)。
// KNOTE 析構函數 - 錯誤根源
template <class A>
KNOTE<A>::~KNOTE() {
delete next; // 遞歸刪除後續節點
}
LI::~LI() 中循環調用 DELETE(1, temp) 逐個刪除節點。DELETE 執行 delete temp_p 釋放當前節點內存。~KNOTE() 再次執行 delete next,嘗試刪除**已被鏈表邏輯移除但尚未析構**的下一個節點。delete 兩次:一次由 LI::DELETE 顯式刪除,一次由析構函數遞歸刪除。delete 作用於已釋放內存(填充模式 0xFEEEFEEE),觸發崩潰。template <class A>
KNOTE<A>::~KNOTE() {
// delete next; // 註釋掉或刪除此行
next = nullptr; // 良好習慣:置空防懸空指針
}
鏈表容器 LI 負責統一管理節點生命週期,節點本身不應擁有後續節點的所有權。
template <class A>
class KNOTE {
public:
A data;
std::unique_ptr<KNOTE> next; // 獨占所有權,自動遞歸釋放
KNOTE(A data, std::unique_ptr<KNOTE>&& next)
: data(data), next(std::move(next)) {}
// 無需顯式析構函數
};
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF)。Application Verifier 捕獲雙重釋放。this 指針,追蹤釋放順序。