Segmentation fault (core dumped) when I delete pointer(当我删除指针时出现分段错误(核心转储))
问题描述
我正在尝试从链表中删除重复项,但遇到了一个问题,这可能很明显而且很简单,但我已经很多年没有使用过 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 ©_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
.然后我意识到你只delete
你new
.很公平,但是在 main
中构建整个列表时,我正在 new
对每个 Node
进行处理:
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 new
ing 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
那么为什么我不能delete
在其他地方new
的东西呢?是不是因为它在当前范围之外被new
编辑了?
So why I am not allowed to delete
something that was new
ed somewhere else? Is it because it was new
ed outside the current scope?
第二,free
ing 空间工作正常,但显然不是正确的做法,因为我没有 malloc
而是 new
ed!
Second, free
ing the space works fine, but obviously not the right thing to do because I didn't malloc
but new
ed!
我做错了什么?如何正确杀死已删除的节点?
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 分配的.NathanOliver 的回答已经涵盖了这一点,但隐藏在下面的是
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 获取 delete
d.它调用它们的析构函数,删除
它们接触的两个节点,并调用将销毁列表中所有节点的死亡风暴.
Next and prev get delete
d. Which calls their destructors, delete
ing the two nodes they touch, and invokes a deathstorm that will destroy all of the Nodes in the list.
如果双重删除没有首先杀死程序.每个链接节点都会尝试delete
刚刚删除
它们的节点.不好.
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 Node
s to the LinkedList
class.
这篇关于当我删除指针时出现分段错误(核心转储)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:当我删除指针时出现分段错误(核心转储)
- STL 中有 dereference_iterator 吗? 2022-01-01
- 使用/clr 时出现 LNK2022 错误 2022-01-01
- 如何对自定义类的向量使用std::find()? 2022-11-07
- 近似搜索的工作原理 2021-01-01
- 与 int by int 相比,为什么执行 float by float 矩阵乘法更快? 2021-01-01
- Stroustrup 的 Simple_window.h 2022-01-01
- 静态初始化顺序失败 2022-01-01
- 一起使用 MPI 和 OpenCV 时出现分段错误 2022-01-01
- 从python回调到c++的选项 2022-11-16
- C++ 协变模板 2021-01-01