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

MFC 0xC0000005 訪問沖突:空指針與釋放後使用排查

     編輯:程式設計綜合問答

錯誤現象

未經處理的異常: 0xC0000005: 讀取位置 0x0000002C 時發生訪問沖突。
atlsimpstr.h: CStringData* GetData() { return (CStringData*)(m_pszData) - 1; }

根因分析

m_pszData == 0x0000002C 即 44 字節偏移,說明 CString 內部指針指向已釋放或未初始化的內存。典型場景:

  1. 臨時 CString 引用:
    void Func() {
        CString s = GetString();  // 返回局部對象引用
        Use(s);  // s 已析構,內存釋放
    }
  2. 容器存儲指針未深拷貝:
    CArray arr;
    arr.Add(new CString("temp"));
    // 別處 delete 了指針,arr 仍持有野指針
    
  3. 跨模塊傳遞 CString:DLL/EXE 使用不同 CRT 堆,一方釋放另一方訪問。

排查步驟

  1. 啟用 PageHeap:gflags /p /enable MyApp.exe /full,崩潰點精確定位到錯誤釋放處。
  2. 檢查調用棧:雙擊斷點處 atlsimpstr.h,向上找到業務代碼行。
  3. 添加斷點監視可疑指針變化。

修復模式

模式錯誤代碼修正代碼
返回局部引用CString& Get() { CString s; return s; }CString Get() { return CString("val"); } (返回值優化)
容器存指針CArrayCArray 或 std::vector
跨模塊DLL 導出 CString導出 const char* / BSTR,調用端構造 CString

預防清單

  • ✅ 優先用 CString 值語義,避免裸指針。
  • ✅ 容器存對象而非指針(CArray、std::vector)。
  • ✅ DLL/EXE 統一 動態鏈接 CRT (/MD /MDd),確保堆一致。
  • ✅ 代碼審查關注「誰負責釋放」、「生命週期邊界」。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved