首頁  >  問答  >  主體

C++链表节点删除方法,如何合适的释放内存

让我先描述下……

实现这样一个方法,删除不带头单链表中与val值相同的结点
方法签名:

ListNode* removeElements(ListNode* head, int val);

ListNode类声明

class ListNode {
public:
    ListNode(int x) : val(x), next(NULL) {}
    int val;
    ListNode *next;
};

逻辑很简单,当

// ...
pre->next = p->next;
// ...

之后,一般的做法是

delete p;

但这时,有个问题。当主调函数中写如下调用时,会出内存问题

ListNode n0(0), n1(1), n2(2);
n0.next = &n1;
n1.next = &n2;
// ...
removeElements(&n0, 2);

n2结点的内存是不可delete的……

另外,如果在removeElements方法中不写delete逻辑,如果主调函数中,链表结点是new出来的,则不delete会内存泄露

So… 我想问一下,在实现类似的C++函数时,有什么一般的做法,或者业内默认规定?
或者,有没有更nice的处理方式?能让方法比较安全且避免内存泄露

多谢 :-)

伊谢尔伦伊谢尔伦2765 天前636

全部回覆(5)我來回復

  • 黄舟

    黄舟2017-04-17 11:56:48

    既然有ListNode ,就應該有List類,將removeElements封裝到List類中,由List類負責記憶體的分配與釋放;
    這樣責任就清楚了。

    再就是結點的分配一般都是在堆上申請,在棧上連接起來的結點當然無法刪除;
    如果非得需要按照你這樣的實現,在棧上應用list,那麼只用更改結點指針就好了,不用delete,棧上的即結點在退出程序邏輯範圍時自動刪除了;

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 11:56:48

    最不動腦子的方法,用shared_ptr,當然在你這個問題中這樣顯得有點傻。
    所以你應該把所有要刪除的節點放到另一個list裡,等到真的不用的時候統一刪掉就好。

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 11:56:48

    你這種寫法,不只是n2刪除有問題,n0也有問題。
    考慮在removeElements中對錶頭和錶尾做特殊處理,雙鍊錶

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 11:56:48

    可以考慮removeElements介面傳入一個回呼函數,讓使用者自行決定是否釋放

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 11:56:48

    誰提供的內存, 誰負責釋放. 例如如果Node是在你的類庫代碼里分配的內存, 那麼你的類庫代碼負責釋放; 如果是用戶傳入的內存, 則用戶負責.

    回覆
    0
  • 取消回覆