让我先描述下……
实现这样一个方法,删除不带头单链表中与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的处理方式?能让方法比较安全且避免内存泄露
多谢 :-)
Since there is a ListNode, there should be a List class, encapsulate removeElements into the List class, and the List class is responsible for memory allocation and release;
This way the responsibilities are clear.
Furthermore, node allocation is generally applied on the heap. Of course, nodes connected on the stack cannot be deleted;
If you have to implement a list like yours and apply a list on the stack, then you only need to change the node pointer. No need to delete. The node on the stack will be automatically deleted when it exits the program logic scope;
The most mindless method is to use
shared_ptr
, which of course seems a bit silly in your question.So you should put all the nodes to be deleted in another list, and delete them all when they are no longer needed.
Your way of writing is not only problematic when deleting n2, but also when n0 is deleted.
Consider doing special processing on the header and tail of the table in removeElements, doubly linked list
You can consider passing in a callback function through the removeElements interface to let the user decide whether to release it
Whoever provides the memory is responsible for releasing it. For example, if Node is allocated memory in your class library code, then your class library code is responsible for releasing it; if it is memory passed in by the user, the user is responsible.