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

C++鏈式棧pop操作邏輯解析:指針移動與內存釋放疑問

     編輯:程式設計綜合問答

代碼片段分析

int pop() {
    int value;
    value = ptrf->data;      // 1. 保存棧頂數據
    // top = ptrf;            // 2. 臨時保存待刪除節點(註釋掉了)
    ptrf = ptrf->next;       // 3. 棧頂指針後移
    // delete top;            // 4. 釋放原棧頂節點內存(註釋掉了)
    return value;
}

疑問解答

Q: 「因為19行代碼說是NULL,那麼這裡的ptrf不就也為NULL了?」

A: 這裡有誤解。`ptrf = ptrf->next;` 是將 `ptrf` 指向下一個節點。只有當彈出的是最後一個節點時,`ptrf->next` 為 `NULL`,賦值後 `ptrf` 才變為 `NULL`(表示棧空)。這正是正確邏輯。

完整正確的pop實現

int pop() {
    if (ptrf == nullptr) {
        throw runtime_error("Stack underflow");
    }
    int value = ptrf->data;
    ListNode* top = ptrf;      // 保存當前棧頂節點地址
    ptrf = ptrf->next;         // 棧頂指針下移
    delete top;                // 釋放原棧頂節點內存,防止內存洩漏
    if (ptrf == nullptr) {     // 若彈出後棧空,尾指針也需置空
        ptrb = nullptr;
    }
    return value;
}

關鍵點總結

  • 先保存數據,再移動指針,最後釋放內存,順序不可亂
  • 單向鏈表棧只需維護頭指針`ptrf`,尾指針`ptrb`僅在push/pop導致棧空/非空轉換時更新
  • 註釋掉`delete`會導致內存洩漏,長時間運行程序會耗盡內存
  • `ptrf = ptrf->next` 不會「把ptrf變成NULL」,而是指向下一個節點;只有下一個節點不存在時才會變NULL

圖解:彈出操作前後

彈出前:  ptrf -> [Node1: data=10, next] -> [Node2: data=20, next] -> NULL
                    ↑
                   top (待刪除)

彈出後:  ptrf --------------------------> [Node2: data=20, next] -> NULL
                    (Node1內存已釋放)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved