c-删除指针时出现分段错误(内核已转储)
作者:互联网
我正在尝试从链接列表中删除重复项,并且遇到了一个问题,该问题可能很明显而且很直接,但是我已经很多年没有使用C了,因此我无法通过阅读类似的问题来找出我做错了什么.
以下是我的代码的一部分.我删除了不相关的部分(例如,构造函数,其他方法等).
template<class T>
class Node {
Node() : data(NULL), next(NULL), prev(NULL) {}
explicit Node(T d) : data(d), next(NULL), prev(NULL) {}
explicit Node(T d, Node<T> *nxt, Node<T> *prv) : data(d), next(nxt), prev(prv) {}
~Node() { delete next; delete prev; }
T data;
Node *next;
Node *prev;
};
template<class T>
class LinkedList {
LinkedList() : head(NULL) {}
explicit LinkedList(Node<T> *head_node) : head(head_node) {}
LinkedList& operator=(const LinkedList ©_list);
~LinkedList(); //didn't implement this but I guess delete head is all?
Node<T>* head;
};
template<class T>
LinkedList<T> RemoveDuplicates(const LinkedList<T> &linked_list) {
//my = overload creates a whole new list with the same data as the original one
LinkedList<T> result = linked_list;
Node<T> *cur = result.head;
Node<T> *prev = NULL;
while (cur) {
if (...) { //duplicate found
Node<T> *temp = cur;
prev->next = cur->next;
cur = cur->next;
cur->prev = prev;
free(temp); //Here is my problem!!!
}
else {
prev = cur;
cur = cur->next;
}
}
return result;
}
因此,首先,我确实删除了temp,并且遇到了Segmentation Fault.然后,我意识到您只删除了新内容.足够公平,但是在main中构建整个列表时,我正在更新每个Node:
Node<char> *h = new Node<char>('H'); //I have a constructor to handle this
Node<char> *e = new Node<char>('E');
Node<char> *l1 = new Node<char>('L');
Node<char> *l2 = new Node<char>('L');
Node<char> *o = new Node<char>('O');
h->next = e;
h->prev = NULL;
e->next = l1;
e->prev = h;
//and so on
那么,为什么不允许我删除其他地方的新内容呢?是因为它是在当前范围之外更新的吗?
其次,释放空间可以很好地工作,但是显然不是正确的选择,因为我不是malloc而是更新的!
我究竟做错了什么?如何正确杀死那个被删除的节点?
Edit1:根据对我帖子的回复,使其更具描述性
Edit2:添加了3种方法的规则
解决方法:
这是其他答案的附录,这些答案可以正确地识别和解决OP的紧迫问题.需要快速浏览以解释接下来会发生什么.
Node<T> *temp = cur;
prev->next = cur->next;
cur = cur->next;
cur->prev = prev;
此时温度尚未清除,因此next和prev仍指向以前环绕cur的两个节点,现在链接在一起.如果不这样做,将导致严重的问题:
free(temp); //Here is my problem!!!
free失败,因为temp指向的值是由new分配的. NathanOliver的答案涵盖了这一点,但是潜伏在下面的是
delete temp;
这将调用析构函数像一个好的小对象一样进行清理.不幸的是,Node析构函数如下所示:
~Node() { delete next; delete prev; }
temp-> next仍指向活动节点. temp-> prev也是如此.
下一个和上一个被删除.它将调用其析构函数,删除它们接触的两个节点,并引发死亡风暴,该风暴将破坏列表中的所有节点.
如果两次删除不首先终止程序.每个链接的节点将尝试删除刚刚删除它们的节点.不好.
奇怪的是,Node析构函数应该只照顾自己,而将其他Node的破坏留给LinkedList类.
标签:duplicate-removal,c,pointers,segmentation-fault,linked-list 来源: https://codeday.me/bug/20191013/1908306.html