在传递给函数

时间:2015-07-22 03:08:02

标签: c++ tree new-operator

根据我对C ++的理解,使用new"运算符初始化的任何变量都将存储在堆上(假设堆内存已成功分配),直到调用相应的“delete”,而本地变量则是仅适用于其包含块的范围。

Node* BTree::insertIntoTree(Node* node, int value) {
   Node* newNode;
   if (node == NULL) {
      newNode = new Node(value);
   } else {
      if (value <= node->myValue) {
          newNode = insertIntoTree(node->leftChild, value);
      } else {
          newNode = insertIntoTree(node->rightChild, value);
      }   
   }   
   return newNode;
}


void BTree::insert(int value) {
    Node* newNode;
    newNode = insertIntoTree(root, value);
    return;
}

在我的代码中,我正在尝试将节点插入二叉树。我通过递归遍历树并使用“new”运算符初始化要插入的节点来实现。然后我返回这个新插入的节点的地址备份递归链。但是,当我尝试遍历树并打印所有值时,即使我多次调用insertIntoTree,我的树仍然是空的,请求我相信我错过了新的运算符。

我将实现更改为以下,这对于我的树为空并且插入新节点作为根的情况成功运行。但是,我仍然无法获得任何根节点的叶节点初始化。我的问题是,为什么用 insertIntoTree(Node * node,int value)中的“new”构造函数初始化节点是不是按照我的预期工作了?

void BTree::insert(int value) {
    Node* newNode;
    if (isEmpty()) {
        root = new Node(value); 
    } else {
        newNode = insertIntoTree(root, value);
    } 
    return;
}

更新 嘿所有,

我刚刚将代码更改为以下内容:

void BTree::insertIntoTree(Node* node, int value) {
    if (node == NULL) {
        node = new Node(value);
    } else {
        if (value <= node->myValue) {
            insertIntoTree(node->leftChild, value);
        } else {
            insertIntoTree(node->rightChild, value);
        }   
    }   
    return;
}

void BTree::insert(int value) {
    insertIntoTree(root, value);
    return;
}

代码仍未按预期运行,每当我尝试读取已插入树中的任何节点的值时,我都会收到分段错误。如果我在我的节点参数上调用new运算符,那么不应该为该节点参数动态分配内存吗?

3 个答案:

答案 0 :(得分:0)

我不会在此代码中看到您为这些字段分配任何内容:

node->leftChild
node->rightChild

所以你正在创建节点,但它们只是取消链接。 在您的第二版代码中,root被分配,但是剩余的节点最终都被取消链接。

例如, 第一次调用insert(int value)时,将创建root并返回函数

第二次调用insert(int value),

  • 使用node = root,
  • 调用insertIntoTree(Node * node,value)
  • 反过来又再次调用insertIntoTree(Node * node,value),这次使用node = null
  • 您创建一个新节点并将其返回
  • 递归返回相同的节点
  • 最后将其分配给插入函数中的newNode 最后newNode被泄露,因为它没有分配给树内的任何东西

答案 1 :(得分:0)

试试这个:

Node* BTree::insertIntoTree(Node* node, int value) {
   if (node == NULL) {
      node = new Node(value);
   } else {
      if (value <= node->myValue) {
         // This makes sure that node->leftChild gets a new Node
         // when it is NULL. If it is not NULL, the assignment is a
         // noop.
          node->lefChild = insertIntoTree(node->leftChild, value);
      } else {
         // This makes sure that node->rightChild gets a new Node
         // when it is NULL. If it is not NULL, the assignment is a
         // noop.
          node->rightChild = insertIntoTree(node->rightChild, value);
      }   
   }   
   return node;
}

void BTree::insert(int value) {
    // This makes sure that root gets a new Node
    // when it is NULL. If it is not NULL, the assignment is a
    // noop.
    root = insertIntoTree(root, value);
    return;
}

答案 2 :(得分:0)

通过检查,您的代码似乎一直向下工作并返回insert。然后:

void BTree::insert(int value) {
  Node* newNode;
  newNode = insertIntoTree(root, value);
  return;
}

调用insertIntoTree后,指针newNode指向新创建的节点。然后控制从insert传出,指针超出范围,节点丢失。