[英]Seg fault in my delete operation in c++
i am writing a code for a c++ assignment, it is a dictionary implementation using a binary search tree. 我正在为C ++赋值编写代码,它是使用二进制搜索树的字典实现。 My code compiles but when i try to "remove" i get a seg Fault.
我的代码可以编译,但是当我尝试“删除”时,出现段错误。 any ideas why did might be happening.
任何想法为什么会发生。 Thanks
谢谢
Here is my code 这是我的代码
// this function calls the deleteNode function where the deletion is done
void BST::deleteContent(string *word)
{
deleteNode(word, root);
}
// a helper fuuntion for the deletecontent function
//uses recursion to find the node to be deleted
void BST::deleteNode(const string *word, Node *&nodePtr)
{
if(word < nodePtr->word)
deleteNode(word, nodePtr->left);
else if(word > nodePtr->word)
deleteNode(word, nodePtr->right);
else
makeDeletion(nodePtr);
}
// a helper function for the deleteNode function
void BST::makeDeletion(Node *&nodePtr)
{
Node *tempNodePtr;
if(nodePtr == NULL)
cout<< "cannot delete empty node. \n";
// if node has no right child
else if (nodePtr->right == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->left; // reattach child
delete tempNodePtr;
}
else if(nodePtr-> left == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // reattach child
delete tempNodePtr;
}
// if node has 2 children
else
{
tempNodePtr = nodePtr->right;
while (tempNodePtr->left)
tempNodePtr = tempNodePtr->left;
tempNodePtr->left = nodePtr->left;
tempNodePtr = nodePtr;
nodePtr = nodePtr->right;
delete tempNodePtr;
}
}
EDIT : 编辑 :
Thank you all!! 谢谢你们!! From your post i realised it was a good idea to check if the node was the last and had no children.
从您的帖子中,我意识到检查节点是否为最后一个节点并且没有子节点是个好主意。 I added this check in deleteNode
我在deleteNode中添加了此检查
if((nodePtr->left) && word < nodePtr->word)
{
do something
}
i did the same for the right it worked and did not throw any errors or seg faults. 我做了正确的工作,没有抛出任何错误或段错误。 Thanks so much!!!!
非常感谢!!!!
Case 1: Empty tree: 情况1:空树:
Suppose your your tree is empty: root
will be nullptr
. 假设您的树为空:
root
将为nullptr
。 So deleteContent()
will call deleteNode()
with argument nullptr
for nodePtr
. 所以
deleteContent()
将调用deleteNode()
与参数nullptr
为nodePtr
。
The first thing you do there is compare word
with nodePtr->word
without first checking that nodePtr
is not nullptr
. 你在那里做的第一件事是比较
word
与nodePtr->word
不先检查nodePtr
不nullptr
。 THere you have a first case of segmenation fault ! 这是您出现分割错误的第一种情况!
Case 2: Delete a word which is not in the tree: 情况2:删除不在树中的单词:
In this case, deleteNode()
will be called recursively until reaching a leaf node with no descendent. 在这种情况下,将递归调用
deleteNode()
直到到达没有后代的叶节点。 As the searched word does not exist in the tree, it's either geater or lesser than nodePtr->word, but never equal. 由于搜索到的单词在树中不存在,因此它的名称比nodePtr-> word少,或者小于nodePtr-> word,但绝不相等。
deleteNode()
will then call itself, again passing argument nullptr
for nodePtr
, as in case 1. Again you'll have a segmentation fault ! deleteNode()
然后将调用本身,再次通过论证nullptr
为nodePtr
,如情况1.同样,你将有一个分割的错!
Solution to case 1 and 2: Control nullptr in deleteNode(): 情况1和2的解决方案:在deleteNode()中控制nullptr:
void BST::deleteNode(const string *word, Node *&nodePtr)
{
if (nodePtr==nullptr)
cout << word << " not found in the tree\n";
else if (word < nodePtr->word)
... // the rest as in your original function
}
makeDeletion()
should now be called by deleteNode()
if and only if nodePtr
is not null and word==nodePtr->word
. makeDeletion()
现在应该叫deleteNode()
当且仅当nodePtr
不是null word==nodePtr->word
。 Get rid of the first if() which should no longer be true in any case. 摆脱第一个if()在任何情况下都不再为真。 May be replace it with an assert at to verify the invariant.
可以用断言at代替它以验证不变量。
Case 3: Delete a word in the tree : 情况3:删除树中的单词:
All the three cases seem to work (even leaf nodes with two null pointers), at least if I look at my drawing of your data structure. 至少在我查看数据结构图的情况下,所有这三种情况似乎都起作用(甚至具有两个空指针的叶子节点)。
However I'd suggest to verify Node::~Node()
: in all cases, you reattach the children and then you delete the old node ( temNodePtr
) without having set its children to nullptr
. 但是,我建议您验证
Node::~Node()
temNodePtr
Node::~Node()
:在所有情况下,您都重新附加子节点,然后删除旧节点( temNodePtr
),而无需将其子节点设置为nullptr
。 So I wonder whether ~Node()
just destroys the node without taking care of its children (then makeDeletion()
should work) or if its a recursive destructor, deleteing the node and its children (then makeDeletion()
would not work because, you would delete the nodes that you've just reattached, without noticing it, thus creating a seg.fault at the first occasion). 所以,我想知道是否
~Node()
只是破坏节点,而不考虑其照顾孩子(当时makeDeletion()
应该工作),或者如果它是一个递归的析构函数,delete一个节点和它的孩子(当时makeDeletion()
是行不通的,因为你会删除您刚刚重新连接的节点,而不会引起注意,从而在第一次出现seg.fault)。
By the way, nullptr would perhap's be be more appropriate than NULL for pointers, even if NULL would work properly as well. 顺便说一句,即使NULL也可以正常工作,对于指针,nullptr也许比NULL更合适。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.