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

C 語言循環鏈表 free 導致堆損壞的根因分析與修復

     編輯:程式設計綜合問答

錯誤現象

運行時觸發 CRT detected that the application wrote to memory after end of heap buffer,刪除 DeleteDeath 中的 free(deletePeople) 即不報錯,但會導致內存洩漏。

核心問題:malloc 分配大小錯誤

代碼中:

footer = (ListNode *)malloc(sizeof(LinkList)); // 錯誤:sizeof(LinkList) 是指針大小(4/8 字節)

LinkList 是 ListNode*,sizeof(LinkList) 返回指針大小,遠小於 sizeof(ListNode),導致寫入 footer->name 時越界破壞堆元數據,隨後 free 觸發崩潰。

修正代碼要點

  1. 分配正確大小:malloc(sizeof(ListNode))。
  2. 修正環形鏈表構建邏輯:尾節點 next 指向頭節點,並返回正確頭指針。
  3. 刪除節點時正確移動指針:先保存 next 再 free。

關鍵修正片段

// InitRing 中
footer = (ListNode *)malloc(sizeof(ListNode)); // 修正這裡
// ...
footer->next = linklist; // 閉環
return linklist; // 返回頭節點

// DeleteDeath 中
for (j = 1; j <= countOffLimits - 1; j++) // 修正步進邏輯
    slider = slider->next;
deletePeople = slider->next;
slider->next = deletePeople->next;
free(deletePeople); // 現在安全

調試建議

  • 使用 Valgrind 或 AddressSanitizer 定位堆越界。
  • 养成 malloc(sizeof(*ptr)) 習慣,避免類型變更導致大小錯誤。
  • 釋放後將指針置 NULL,防止二次釋放。

修正分配大小與指針邏輯後,程序可穩定運行,正確實現約瑟夫環問題。

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