如何删除存储在节点中的指针?
How to delete a pointer stored within a node?
我正在尝试建立一个由包含指向对象指针的节点组成的二叉树,但是在我的“清除树”函数中,我在尝试释放节点内指针处的内存时遇到读取访问冲突.为什么我在根指针释放内存时没有抛出异常,而在节点内的int指针却有?
抛出异常:读取访问冲突。
它 是 0x2。
class Tree {
private:
struct Node {
int* val = nullptr;
Node* right = nullptr;
Node* left = nullptr;
};
Node* root = nullptr;
public:
bool Insert(int* num);
void Empty();
bool isEmpty() const;
};
void Tree::Empty()
{
while (!(root == nullptr)) // Just handling the simplest case for now
{
if (root->left == nullptr && root->right == nullptr)
{
delete root->val; // Read access violation
delete root;
root = nullptr;
break;
}
[...]
}
}
bool Tree::Insert(int* num)
{
Node* insertion = new Node;
int* temp = new int(*num);
insertion->val = temp;
if (root == nullptr)
{
root = insertion;
return true;
}
Node* c_node = root;
while (true)
{
if (*temp == *c_node->val)
{
delete temp;
delete insertion;
return false;
}
if (*temp > *c_node->val)
{
if (c_node->right != nullptr)
{
c_node = c_node->right;
continue;
}
c_node->right = insertion;
return true;
}
if (c_node->left != nullptr)
{
c_node = c_node->left;
continue;
}
c_node->left = insertion;
return true;
}
}
int main()
{
int a = 2;
Tree my_tree;
my_tree.Insert(&a);
my_tree.Empty();
}
如果有任何反馈,我将不胜感激!
我建议首先让 Node
对自己的内容负责:
struct Node {
Node(int *val) : val(new int(*val)) { }
int* val = nullptr;
Node* right = nullptr;
Node* left = nullptr;
~Node() { delete val; }
};
完成后,我们可以稍微简化 Empty
(和 Insert
)的代码,让它处理它存储的值,所以 Empty
的片段你到目前为止实施的结果是这样的:
void Tree::Empty()
{
while (!(root == nullptr)) // Just handling the simplest case for now
{
if (root->left == nullptr && root->right == nullptr)
{
delete root;
root = nullptr;
break;
}
}
}
至于使此实现适用于具有多个节点的树,我可能会递归地执行此操作:
void Tree::Empty(Node *node)
{
if (node == nullptr)
return;
Empty(node->left);
Empty(node->right);
delete node;
}
我可能还会为 Tree
定义一个 dtor,因此用户不需要显式调用 Empty
(事实上,我可能会将 Empty
设为私有,所以外界根本称不上它,但这是一个单独的问题)。
我正在尝试建立一个由包含指向对象指针的节点组成的二叉树,但是在我的“清除树”函数中,我在尝试释放节点内指针处的内存时遇到读取访问冲突.为什么我在根指针释放内存时没有抛出异常,而在节点内的int指针却有?
抛出异常:读取访问冲突。 它 是 0x2。
class Tree {
private:
struct Node {
int* val = nullptr;
Node* right = nullptr;
Node* left = nullptr;
};
Node* root = nullptr;
public:
bool Insert(int* num);
void Empty();
bool isEmpty() const;
};
void Tree::Empty()
{
while (!(root == nullptr)) // Just handling the simplest case for now
{
if (root->left == nullptr && root->right == nullptr)
{
delete root->val; // Read access violation
delete root;
root = nullptr;
break;
}
[...]
}
}
bool Tree::Insert(int* num)
{
Node* insertion = new Node;
int* temp = new int(*num);
insertion->val = temp;
if (root == nullptr)
{
root = insertion;
return true;
}
Node* c_node = root;
while (true)
{
if (*temp == *c_node->val)
{
delete temp;
delete insertion;
return false;
}
if (*temp > *c_node->val)
{
if (c_node->right != nullptr)
{
c_node = c_node->right;
continue;
}
c_node->right = insertion;
return true;
}
if (c_node->left != nullptr)
{
c_node = c_node->left;
continue;
}
c_node->left = insertion;
return true;
}
}
int main()
{
int a = 2;
Tree my_tree;
my_tree.Insert(&a);
my_tree.Empty();
}
如果有任何反馈,我将不胜感激!
我建议首先让 Node
对自己的内容负责:
struct Node {
Node(int *val) : val(new int(*val)) { }
int* val = nullptr;
Node* right = nullptr;
Node* left = nullptr;
~Node() { delete val; }
};
完成后,我们可以稍微简化 Empty
(和 Insert
)的代码,让它处理它存储的值,所以 Empty
的片段你到目前为止实施的结果是这样的:
void Tree::Empty()
{
while (!(root == nullptr)) // Just handling the simplest case for now
{
if (root->left == nullptr && root->right == nullptr)
{
delete root;
root = nullptr;
break;
}
}
}
至于使此实现适用于具有多个节点的树,我可能会递归地执行此操作:
void Tree::Empty(Node *node)
{
if (node == nullptr)
return;
Empty(node->left);
Empty(node->right);
delete node;
}
我可能还会为 Tree
定义一个 dtor,因此用户不需要显式调用 Empty
(事实上,我可能会将 Empty
设为私有,所以外界根本称不上它,但这是一个单独的问题)。