首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ 學習筆記 Day 1:鏈表實現棧與內存洩漏排查

     編輯:C++ 入門

背景

準備跳槽,重拾 C++ 復習數據結構。第一天實現基於鏈表的棧,過程中遇到經典內存錯誤,記錄以自勉。

棧類設計

  • 內部節點結構:data (int) + next 指針。
  • 棧頂指針 header。
  • 支持操作:構造、析構、入棧 addElement、出棧 popElement、判空、打印、查找。

關鍵代碼片段

class Stack {
private:
    typedef int NODE_DATA_TYPE;
    typedef struct Node {
        NODE_DATA_TYPE data;
        struct Node *next;
    } Node;
    Node *header;

public:
    Stack() : header(nullptr) {}
    ~Stack() {
        while (header) {
            Node *temp = header;
            header = header->next;
            free(temp);
        }
        _ASSERTE(_CrtCheckMemory()); // 檢查內存洩漏
    }
    void addElement(NODE_DATA_TYPE data) {
        Node *newNode = (Node*)malloc(sizeof(Node)); // 關鍵:sizeof(Node) 而非 sizeof(Node*)
        newNode->data = data;
        newNode->next = header;
        header = newNode;
    }
    NODE_DATA_TYPE popElement() {
        if (!header) return -1;
        NODE_DATA_TYPE val = header->data;
        Node *temp = header;
        header = header->next;
        free(temp);
        return val;
    }
    // ... 其他方法
};

踩坑記錄:malloc(sizeof(Node*)) 導致堆損壞

錯誤現象:在 free(temp) 時觸發 CRT detected that the application wrote to memory after end of heap buffer。

原因:分配內存時寫成 malloc(sizeof(Node*)),只分配了指針大小(4/8 字節),而非結構體大小。寫入 data 和 next 時越界破壞堆元數據。

教訓:sizeof(Node) 是結構體大小,sizeof(Node*) 是指針大小,兩者差異極大。動態分配結構體時務必用 sizeof(結構體類型)。

內存檢查技巧

  • MSVC 調試模式下使用 _CrtCheckMemory() 檢測堆完整性。
  • 析構函數中遍歷釋放所有節點,防止內存洩漏。
  • _ASSERTE 宏在條件失敗時中斷,便於定位問題。

其他細節

  • 構造函數重載:默認構造、帶初始值構造。
  • searchElement 中修改了 header 導致棧內容丟失,應使用臨時指針遍歷。
  • C++ 推薦用 new/delete 替代 malloc/free,但理解底層分配機制有助於排查錯誤。

總結

看似簡單的棧實現,蘊含指針操作、內存管理、調試技巧等核心功力。一個 sizeof 的細微錯誤纏繞一晚,正是「細節決定成敗」的生動寫照。繼續保持,戰鬥不退縮!

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