删除指针时出现分段错误(核心转储) [英] Segmentation fault (core dumped) when I delete pointer

查看:33
本文介绍了删除指针时出现分段错误(核心转储)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从链表中删除重复项,遇到了一个问题,这个问题可能很明显也很简单,但我已经很多年没有使用 C++ 了,我无法找出是什么通过阅读有关 SO 的类似问题,我做错了.

I am trying to remove duplicates from a linked list, and encountered a problem, which is probably obvious and straightforward but I haven't used C++ in many years and I couldn't find out what I am doing wrong by reading similar questions on SO.

以下是我的部分代码.我删除了不相关的部分(例如构造函数、其他方法等).

Below is parts of my code. I removed irrelevant parts (eg. constructors, other methods, etc).

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;
}

所以首先,我做了delete temp 并且我得到了Segmentation fault.然后我意识到你只deletenew.很公平,但是在 main 中构建整个列表时,我对每个 Node 进行了 new 处理:

So first, I did delete temp and I got Segmentation fault. I then realized you only delete what you new. Fair enough, but I am newing each Node when building the whole list in main:

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

那为什么我不能删除在别处的东西?是不是因为它在当前范围之外被new?

So why I am not allowed to delete something that was newed somewhere else? Is it because it was newed outside the current scope?

其次,free空间工作正常,但显然不是正确的做法,因为我没有malloc而是newed!

Second, freeing the space works fine, but obviously not the right thing to do because I didn't malloc but newed!

我做错了什么?如何正确杀死删除的节点?

What am I doing wrong? How to properly kill that removed node?

Edit1:根据对我帖子的回复使其更具描述性Edit2:添加了 3 种方法的规则

Made it more descriptive according to replies to my post Rule of 3 methods added

推荐答案

这是其他答案的附录,可以正确识别和解决 OP 的紧迫问题.需要快速浏览以解释接下来会发生什么.

This is an addendum to other answers which correctly identify and solve the OP's immediate problem. A quick walk-though is required to explain what will happen next.

  Node<T> *temp = cur;
  prev->next = cur->next;
  cur = cur->next;
  cur->prev = prev;

此时 temp 还没有被清除,所以 next 和 prev 仍然指向曾经围绕着 cur 并且现在链接在一起的两个节点.如果不是因为:

At this point temp has not been cleared so next and prev still point to the two nodes that used to surround cur and are now linked together. This will cause serious problems if not for:

  free(temp); //Here is my problem!!!

free 失败,因为 temp 指向的值是由 new 分配的.内森奥利弗的回答已经涵盖了这一点,但潜伏在下面的是

free fails because the value pointed to by temp was allocated by new. NathanOliver's answer has this covered, but lurking beneath is what will happen with

delete temp;

这将调用析构函数像一个好的小对象一样清理.不幸的是,Node 析构函数看起来像这样:

This will invoke the destructor to clean up like a good little object. Unfortunately the Node destructor looks like this:

~Node() { delete next; delete prev; }

temp->next 仍然指向一个活动节点.temp->prev 也是如此.

temp->next still points to a live node. So does temp->prev.

Next 和 prev 得到 deleted.它调用它们的析构函数,删除它们接触的两个节点,并调用一个死亡风暴来摧毁列表中的所有节点.

Next and prev get deleted. Which calls their destructors, deleteing the two nodes they touch, and invokes a deathstorm that will destroy all of the Nodes in the list.

如果双删除不先杀死程序.每个链接的节点都会尝试删除刚刚删除它们的节点.不好.

If the double-deletes don't kill the program first. Each linked node will try to delete the node that just deleted them. Not good.

很可能 Node 析构函数应该自己照顾自己并将其他 Node 的销毁留给 LinkedList 类.

Odds are pretty good that the Node destructor should just look after itself and leave the destruction of the other Nodes to the LinkedList class.

这篇关于删除指针时出现分段错误(核心转储)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆