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

MFC 鏈表操作導致「內存不能為 read」?核心原因其實是數組越界

     編輯:程式設計綜合問答

從崩潰堆疊到真兇:一個經典的 MFC 新手坑

現象:運行到鏈表賦值邏輯時拋出「內存不能為 read」,代碼片段涉及 CURVE_DATA *first_node=NULL;、data_head=first_head; 等指針操作。初學者往往誤以為是鏈表指針鏈接錯誤,實則不然。

真相重現:深度數組 depth[ROW] 定義過小

排查發現,錯誤發生在後續的深度計算循環中:

float depth[ROW]; // ROW 定義太小
int lineNum = (maxDepth - minDepth) / delta; // 實際需要元素數
for (int row = 0; row < lineNum; row++) {
    depth[row] = minDepth + delta * row; // 越界寫入,破壞堆棧
}

當 lineNum > ROW 時,循環寫入超出數組邊界,破壞相鄰變量(如鏈表指針),導致後續解引用時讀取到垃圾地址,拋出「不能 read」。

修復方案

  1. 動態分配: 用 std::vector depth(lineNum); 或 new float[lineNum] 替換固定大小數組。
  2. 邊界斷言: 循環前加 ASSERT(lineNum <= ROW); 或 if (lineNum > ROW) return ERROR;。
  3. 現代化重構: 棄用原始鏈表,改用 std::list<CURVE_DATA> 或 std::vector<CURVE_DATA>,配合智能指針自動管理內存。

調試心法

  • 「內存不能 read/write」90% 是越界或野指針,優先檢查數組下標、指針解引用前是否為 NULL。
  • 開啟 /RTCsu(運行時檢查)或使用 Application Verifier、Visual Studio 內存診斷工具定位首次越寫點。
  • MFC 專項:CArray、CList 等容器類已處理擴容與邊界,優先於手工 new/delete。
補充:若確需手工管理鏈表,請嚴格遵循「分配即初始化、刪除即置空、遍歷不修改結構」三原則。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved