其他分享
首页 > 其他分享> > c-删除指针时出现分段错误(内核已转储)

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 &copy_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