使用指针的分段错误
嗨,我正在为表示为树的堆编写一些函数。我的节点是一个结构:
template<typename Object>
struct Node
{
Node * parent = nullptr;
Object name;
Node * left = nullptr;
Node * right = nullptr;
Node(Object n) : name(n){}
};
而我的班级有一个私有变量叫做 root,它是树的根。以下是导致问题的函数,特别是 insert_spot:
template<typename Object>
void MyPriorityQueue<Object>::insert(const Object & elem)
{
Node<Object> n_node = Node(elem);
Node<Object> * new_node = &n_node;
if (cur_amount > level_amount)
{
cur_amount = 1;
level += 1;
level_amount += level_amount;
}
if (root == nullptr)
{
root = new_node;
cur_amount += 1;
cur_size += 1;
if (cur_amount > level_amount)
{
cur_amount = 1;
level += 1;
level_amount += level_amount;
}
return;
}
insert_spot(new_node); //insert node at bottom
}
而 insert_spot 是:
void insert_spot(Node<Object> * new_node)
{
Node<Object> * parent_node = root;
unsigned temp_amount = cur_amount;
while (temp_amount > 2)
{
temp_amount -= temp_lvl_amount;
}
if(temp_amount == 1)
{
parent_node->left = new_node;
}
else{parent_node->right = new_node;}
new_node->parent = parent_node;
cur_amount += 1;
cur_size += 1;
}
我知道问题是什么,在 insert_spot 函数中,当我尝试执行 parent_node->left = new_node 或 parent_node->right = new_node 时,会出现分段错误。
1如果我将其替换为(并说对象类型为 int)
Node<Object> n_node = Node(5)
parent_node->left = &n_node;
与 parent_node->right 相同,然后它工作正常。
我以前的代码可以工作,使用“new”运算符来创建指针,但由于后来的一些障碍,我不能在这里使用它。
我认为问题出在 'const Object & elem' 不知何故,但我真的不明白为什么我不能做 parent_node->left = new_node 或 parent_node->right = new_node。
也只是来自 main 的一个示例输入:
MyPriorityQueue<int> test;
test.insert(5);
test.insert(4);
我不是在寻找具体的答案,只是想了解为什么 parent_node-> 会导致分段错误。
回答
这与Object.
这段代码
Node<Object> n_node = Node(elem);
parent_node->left = &n_node;
很快就会导致未定义的行为。一旦insert函数退出,n_node对象就会被销毁。这意味着您的树持有一个指向已被销毁的对象的指针。任何取消引用该指针(例如parent_node->)的尝试都会导致未定义的行为。
无论您遇到什么问题new,都必须克服它们。new(或等效的)是这里需要的。不能使用指向局部变量的指针来构造树。
重点new在于,当退出它们创建的范围时,用它创建的对象不会被销毁。