悬空指针 - 请验证
Dangling Pointer- please verify
有人可以验证并告诉我以下代码是否有效吗?我觉得第 160-162 行可能是错误的。
我有意见指出行号。
完整的代码取自这里 C++ 二叉搜索树
class BinarySearchTree
{
private:
struct tree_node
{
tree_node* left;
tree_node* right;
int data;
};
tree_node* root;
public:
BinarySearchTree()
{
root = NULL;
}
bool isEmpty() const { return root==NULL; }
void print_inorder();
void inorder(tree_node*);
void print_preorder();
void preorder(tree_node*);
void print_postorder();
void postorder(tree_node*);
void insert(int);
void remove(int);
};
void BinarySearchTree::remove(int d)
{
//Locate the element
bool found = false;
if(isEmpty())
{
cout<<" This Tree is empty! "<<endl;
return;
}
tree_node* curr;
tree_node* parent;
curr = root;
while(curr != NULL)
{
if(curr->data == d)
{
found = true;
break;
}
else
{
parent = curr;
if(d>curr->data) curr = curr->right;
else curr = curr->left;
}
}
if(!found)
{
cout<<" Data not found! "<<endl;
return;
}
// 3 cases :
// 1. We're removing a leaf node
// 2. We're removing a node with a single child
// 3. we're removing a node with 2 children
// Node with single child
if((curr->left == NULL && curr->right != NULL)|| (curr->left != NULL
&& curr->right == NULL))
{
if(curr->left == NULL && curr->right != NULL)
{
if(parent->left == curr)
{
parent->left = curr->right;
delete curr;
}
else
{
parent->right = curr->right;
delete curr;
}
}
else // left child present, no right child
{
if(parent->left == curr)
{
parent->left = curr->left;
delete curr;
}
else
{
parent->right = curr->left;
delete curr;
}
}
return;
}
//We're looking at a leaf node
if( curr->left == NULL && curr->right == NULL)
{
if(parent->left == curr) parent->left = NULL;
else parent->right = NULL;
delete curr;
return;
}
//Node with 2 children
// replace node with smallest value in right subtree
if (curr->left != NULL && curr->right != NULL)
{
tree_node* chkr;
chkr = curr->right;
if((chkr->left == NULL) && (chkr->right == NULL))
{
curr = chkr; // <----------- line 160
delete chkr;
curr->right = NULL; // <------------------ line 162
}
else // right child has children
{
//if the node's right child has a left child
// Move all the way down left to locate smallest element
if((curr->right)->left != NULL)
{
tree_node* lcurr;
tree_node* lcurrp;
lcurrp = curr->right;
lcurr = (curr->right)->left;
while(lcurr->left != NULL)
{
lcurrp = lcurr;
lcurr = lcurr->left;
}
curr->data = lcurr->data;
delete lcurr;
lcurrp->left = NULL;
}
else
{
tree_node* tmp;
tmp = curr->right;
curr->data = tmp->data;
curr->right = tmp->right;
delete tmp;
}
}
return;
}
}
curr 和 chkr 指向同一位置。通过删除 chkr,curr 仍然可以访问相同的位置吗?或者这没关系,因为它们实际上都没有使用 new 语句分配任何内存。
代码中有一些非常狡猾的东西。我觉得也有内存泄漏。我是一名在职专业人士,希望刷新我的C++基础知识。感谢您的任何帮助。
我看了一眼你提到的区域周围的代码。我相信你是对的,因为这是一个错误。
void BinarySearchTree::remove(int d)
{
...
tree_node* curr;
tree_node* parent;
curr = root;
...
//Node with 2 children
// replace node with smallest value in right subtree
if (curr->left != NULL && curr->right != NULL)
{
tree_node* chkr;
chkr = curr->right;
if((chkr->left == NULL) && (chkr->right == NULL))
{
curr = chkr;
delete chkr;
curr->right = NULL;
}
在此代码节中,curr 和 chkr 都声明为指向tree_node实例的指针。在运行curr = chkr
时,chkr 的指针值被引导到 curr,因此将 curr 指向 chkr 指向的实例。通过delete chkr
,实例被销毁并被垃圾回收。因此,curr现在指向一个不存在的物体,它已经脱离了生命。如果我没记错的话,根据定义,这是一个悬空的指针。
如果我在上面都是正确的并且对该特定块的理解,以下是解决此问题的方法:
curr->data = chkr->data;
要替换
curr = chkr;
关于内存泄漏。抱歉,我没有阅读整个代码。看起来 msram 的代码应该只是为了显示正确的逻辑。不过,这是更多用于此目的的额外信息。
是的,如您所描述的,第 160-162 行包含错误。 他正在写信给记忆,他已经发布了delete
.
相关文章:
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 运行时错误:引用绑定到类型为"int"的空指针
- 这个失败的测试是将零添加到空指针未定义的行为、编译器错误还是其他什么?
- 为什么我在空指针错误(链表)中获取成员访问权限
- 从向量到空指针的 memcpy(反之亦然)不起作用
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 成员访问是否在空指针上定义C++?
- 尝试将对象插入空指针数组时出现分段错误
- 为什么我们需要在 C++ 中检查空指针,而在 Java 中不需要?
- 是否允许向空指针添加零?
- 为什么 C 样式字符串的工作空指针检查不?
- 在函数内初始化无符号字符指针将返回空指针
- 为什么多维数组中的空字符串文本衰减为空指针?
- C++ 取消引用指向矢量的空指针时的分段错误
- 错误 C6011:取消引用空指针"NAME"。C++
- cppcheck取消引用空指针
- 打印空指针时,std::cout 可以打印 "NULL" 而不是 0 吗?
- 递增空指针无法正确设置值
- Qt - 将空指针(原始数据)转换为 QImage 并将其显示在标签上
- 将多映射转换为空指针,然后转换回多映射