首页 > 解决方案 > C++:私有类指针成员返回未定义的值

问题描述

我正在尝试打印红黑树的级别顺序,但是,指向其他节点的指针在插入 STL 队列后总是返回任何数字。我在这里做错了什么?

这是我的节点类的实现:

// rbtree-node.h
class RBTreeNode
{
public:
  // RBTreeNode(int value, Color color) : value_(value), color_(color), left_(nullptr), right_(nullptr), parent_(nullptr) {}
  RBTreeNode(int value, Color color) : value_(value), color_(color) {}
  ~RBTreeNode()
  {
    delete left_;
    delete right_;
    delete parent_;
  }

  void setLeft(RBTreeNode *node);
  RBTreeNode *getLeft();

  void setRight(RBTreeNode *node);
  RBTreeNode *getRight();

  void setParent(RBTreeNode *node);
  RBTreeNode *getParent();

  void setValue(int value);
  int getValue();

  void setColor(Color color);
  Color getColor();

  bool hasRedChild();
  bool isParentLeftChild();

  void print();

private:
  int value_;
  RBTreeNode *left_ = nullptr;
  RBTreeNode *right_ = nullptr;
  RBTreeNode *parent_ = nullptr;
  Color color_;
};
// rbtree-node.cpp
void RBTreeNode::setLeft(RBTreeNode *node)
{
  this->left_ = node;
}

RBTreeNode *RBTreeNode::getLeft()
{
  return this->left_;
}

void RBTreeNode::setRight(RBTreeNode *node)
{
  this->right_ = node;
}

RBTreeNode *RBTreeNode::getRight()
{
  return this->right_;
}

void RBTreeNode::setParent(RBTreeNode *node)
{
  this->parent_ = node;
}

RBTreeNode *RBTreeNode::getParent()
{
  return this->parent_;
}

void RBTreeNode::setValue(int value)
{
  this->value_ = value;
}

int RBTreeNode::getValue()
{
  return this->value_;
}

void RBTreeNode::setColor(Color color)
{
  this->color_ = color;
}

Color RBTreeNode::getColor()
{
  return this->color_;
}

bool RBTreeNode::isParentLeftChild()
{
  return this->parent_ != NULL && this->parent_->left_ == this;


void RBTreeNode::print()
{
  std::cout << "Value: " << this->value_ << ", Color: " << this->color_ << ", Left: " << this->left_ << ", Right: " << this->right_ << std::endl;
}

然后我插入一个节点:

    // ...
    RBTreeNode node = RBTreeNode(n, BLACK);
    root_ = &node;
    return root_;
    // ...

之后我尝试在这里打印:

void RedBlackTree::printLevelOrder()
{
  // Use BFS in order to print the tree
  std::queue<RBTreeNode *> queue;
  queue.push(root_);

  while (!queue.empty())
  {
    RBTreeNode *current = queue.front();
    std::cout << "Queue: ";
    std::cout << "Value: " << current->getValue() << "(L: " << current->getLeft() << ", R: " << current->getRight() << ") "
              << std::endl;

    if (current->getLeft() != NULL)
    {
      queue.push(current->getLeft());
    }

    if (current->getRight() != NULL)
    {
      queue.push(current->getRight());
    }
    queue.pop();
  }
  std::cout << std::endl;
}

运行它时,我总是遇到分段错误,因为左右节点成员总是返回随机值。

预先感谢您的帮助!

标签: c++classpointerssegmentation-faultclass-members

解决方案


一个问题是您正在队列中存储指向局部变量的指针:

RBTreeNode node = RBTreeNode(n, BLACK);   // locally created value
root_ = &node;   // pointer to local
return root_;    // returning pointer to local.  If used outside the function, undefined behavior

基本上,您应该设计您的代码来保存指向当您通过该指针访问对象时仍然存在的对象的指针。

一种建议是使用动态分配,即

RBTreeNode* node = new RBTreeNode(n, BLACK);
root_ = node; 
return root_; 

当然,您现在必须正确管理内存(使用适当的清理/释放delete等)。

另一种选择是使用智能指针,例如std::unique_ptr,一旦指针超出范围,就会为您处理清理工作。


推荐阅读