【问题标题】:Pointer class member remains NULL after initialization by class method类方法初始化后指针类成员保持为NULL
【发布时间】:2017-01-14 19:06:57
【问题描述】:

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

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

任何帮助或建议都会很有用。下面是相关代码sn-ps。

#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;
}

【问题讨论】:

  • 你需要传递一个指针到你想要修改的东西,就像它是一个int或其他东西一样。
  • 并且初始化发生在构造函数的主体之前。之后就是任务了。
  • 感谢您的回复。你是对的,问题是我传递的是价值而不是引用。从那以后,我更新了类以在不需要指针引用的情况下工作,但至少现在我知道它们了。谢谢!

标签: c++ pointers parameter-passing


【解决方案1】:

在函数中

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

您可以通过使用 this 是类的成员函数这一事实来简单地处理 - root 成员对函数可见。因此,您不需要将其作为参数传递。可以直接在函数内部使用,应该可以解决问题。

【讨论】:

  • 感谢您的回复。你是对的,问题是rnode 是函数本地的。正如上面 cmets 中的 molbdnilo 所指出的,我正在按值传递指针。直到今天,我从未想过通过引用传递指针。我不能在函数中直接使用root,因为类本身不是递归定义的(即,它只是 Node 结构的精美包装器)。我已经对其进行了重组,无需指针引用即可工作。再次感谢您的帮助。
猜你喜欢
  • 2012-02-13
  • 1970-01-01
  • 2017-08-16
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多