指针类成员在通过类方法初始化后保持 NULL

Pointer class member remains NULL after initialization by class method

本文关键字:初始化 NULL 类方法 成员 指针      更新时间:2023-10-16

我正在尝试实现二叉搜索树数据结构。我在使用二叉搜索树类的插入/insert_helper方法初始化我的树时遇到问题。

使用 GDB,我可以看到根数据成员在第一次调用 insert 方法时没有初始化。我很难弄清楚为什么,因为我希望,因为我正在传递指向insert_helper方法的指针,我应该能够在方法本身中初始化该指针。本质上,为什么在第一次调用insert_helper时传递root指针时,我不能正确初始化类root成员?C++有什么规则不允许这样做?

任何帮助或建议都会很有用。以下是相关的代码片段。

#ifndef BST_H_
#define BST_H_
#include <vector>
#include <iostream>
#include <exception>
template <typename T>
class Bin_Search_Tree {
private:
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
    typedef std::size_t size_type;
    struct Node {
    value_type data;
    Node* left;
    Node* right;
    Node* parent;
    };
    Node* root;
    void free_tree(Node* rnode);
    size_type size_helper(const Node* rnode) const;
    Node* find_helper(const Node* rnode, const value_type& val) const;
    void print_tree_helper(const Node* rnode) const;
    bool insert_helper(Node* parent, Node* rnode, const value_type& val);
    bool remove_helper(Node* rnode, const value_type& val);
    Node* create_node(Node* parent, const value_type& val) const;
    Node* get_min(const Node* rnode) const;
public:
    Bin_Search_Tree() : root(nullptr) { }
    Bin_Search_Tree(const std::vector<value_type>& vals);
    ~Bin_Search_Tree() { free_tree(root); }
    bool empty() const { return (nullptr == root); }
    size_type size() const { return size_helper(root); }
    Node* find(const value_type& val) { return find_helper(root, val); }
    bool insert(const value_type& val) { insert_helper(nullptr, root, val); }
    bool remove(const value_type& val);
    void print_tree() const { print_tree_helper(root); }
};
template <typename T>
bool Bin_Search_Tree<T>::insert_helper(Node* parent, Node* rnode, const value_type& val) {
    if (nullptr == rnode) {
    rnode = create_node(parent, val);
    return true;
    } else if (val == rnode->data) {
    return false;
    } else if (rnode->data < val) {
    return insert_helper(rnode, rnode->right, val);
    } else {
    return insert_helper(rnode, rnode->left, val);
    }
}
template <typename T>
typename Bin_Search_Tree<T>::Node* Bin_Search_Tree<T>::create_node(Node* parent, const value_type& val) const {
    Node* inode = new Node;
    if (nullptr == inode) {
    throw std::bad_alloc();
    }
    inode->data = val;
    inode->left = nullptr;
    inode->right = nullptr;
    inode->parent = parent;
    return inode;
}

在函数中

template <typename T>
bool Bin_Search_Tree<T>::insert_helper(Node* parent, Node* rnode, const value_type& val) {
    if (nullptr == rnode) {
    rnode = create_node(parent, val);
    return true;
    } else if (val == rnode->data) {
    return false;
    } else if (rnode->data < val) {
    return insert_helper(rnode, rnode->right, val);
    } else {
    return insert_helper(rnode, rnode->left, val);
    }
}

最初,root=nullptr ,因此满足第一个if条件。然后,使用

rnode = create_node(parent, val);

并返回。但是,rnode是函数的本地,因为您按值传递根。返回时,指针将被销毁,您将无法再访问分配的内存。此外,您从未对root指向的位置进行任何更改,因此它仍然是nullptr

你可以通过使用这是类的成员函数这一事实来简化事情 - root成员对该函数可见。因此,您无需将其作为参数传递。它可以直接在函数内部使用,这应该可以解决问题。