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

MFC 中 vector 成員變量 size 異常增大的排查與解決

     編輯:程式設計綜合問答

現象描述

類中定義 vector<Single*> ans 作為 public 成員。在某函數中 push_back 後 size 正常,ListBox 顯示無誤。但在另一按鈕響應函數 OnLbnDblclkList1 中訪問 ans[m_list.GetCurSel()] 時,ans.size() 突然變為極大值,元素值亂碼,導致「不適當的參數」錯誤。

根因分析

  1. 對象生命週期不匹配:ans 存儲的是指針 Single*。若指針指向的對象在 push_back 後被銷毀(如棧上臨時對象、局部 new 後未保存所有權),隨後訪問即成懸空指針。
  2. 淺拷貝/賦值導致 vector 內部指針失效:若該類被拷貝(如作為參數傳值、返回值),默認拷貝構造函數會淺拷貝 vector 的內部指針,析構時雙重釋放導致堆損壞,後續 size 讀取到垃圾數據。
  3. 內存越界寫入破壞 vector 元數據:其他地方的緩衝區溢出覆蓋了 vector 的 _Myfirst/_Mylast/_Myend 三指針。

解決方案

1. 使用智能指針管理所有權

#include 
#include 
using namespace std;

class MyClass {
public:
    vector> ans;  // 或 unique_ptr 若所有權唯一
    void AddSingle(Single* p) { ans.emplace_back(p); }
};

2. 禁用拷貝,啟用移動語義


class MyClass {
public:
    vector ans;
    MyClass() = default;
    MyClass(const MyClass&) = delete;
    MyClass& operator=(const MyClass&) = delete;
    MyClass(MyClass&&) = default;
    MyClass& operator=(MyClass&&) = default;
    ~MyClass() { for (auto p : ans) delete p; }  // 手動釋放
};

3. 改用值類型存儲(推薦)

若 Single 體積不大且無多態需求,直接存 vector<Single>,避免指針管理麻煩。

4. 調試技巧

  • 在可疑位置打印 ans.data()、ans.size()、ans.capacity() 及首尾元素地址。
  • 啟用「迭代器調試」與「堆檢查」(_ITERATOR_DEBUG_LEVEL=1, _CRTDBG_MAP_ALLOC)。
  • 使用 Application Verifier 或 AddressSanitizer 定位堆損壞來源。

總結

vector size 突變極大值幾乎總是堆損壞或懸空指針導致的內部元數據被破壞。核心對策是明確所有權語義(智能指針/值存儲)、避免淺拷貝、嚴格檢查指針生命週期。

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