3

Trying to teach myself C++ (I normally use Python) and wrote this code.

#include <iostream>
using namespace std;


class TreeNode {
    public:
        TreeNode *left;
        TreeNode *right;
        int value;

        TreeNode(int _value);
        void add_node(TreeNode node);
};

TreeNode::TreeNode(int _value) {
    left = 0;
    right = 0;
    value = _value;
    cout << "Creating node with value: " << value << endl;
}

void TreeNode::add_node(TreeNode node) {
    cout << "Adding " << node.value << " to " << value << endl;
    if (node.value < value) {
        cout << node.value << " < " << value << endl;
        if (left) {
            cout << "Left node of " << value << " exists " << left->value << endl;
            left->add_node(node);
        } else {
            cout << "Left node of " << value << " does not exist" << endl;
            left = &node;
        }
    }
    if (node.value > value) {
        cout << node.value << " > " << value << endl;
        if (right) {
            cout << "Right node of " << value << " exists " << right->value << endl;
            right->add_node(node);
        } else {
            cout << "Right node of " << value << " does not exist" << endl;
            right = &node;
        }
    }
}

int main ()
{
    TreeNode root(25);
    TreeNode n1(15);
    TreeNode n2(30);
    TreeNode n3(20);

    root.add_node(n1);
    root.add_node(n2);
    root.add_node(n3);

    cout << root.left->value << endl;
    cout << root.right->value << endl;

    return 0;
}

The program compiles but runs with results that I don't understand.

Creating node with value: 25
Creating node with value: 15
Creating node with value: 30
Creating node with value: 20
Adding 15 to 25
15 < 25
Left node of 25 does not exist
Adding 30 to 25
30 > 25
Right node of 25 does not exist
Adding 20 to 25
20 < 25
Left node of 25 exists 20
Adding 20 to 20
20
20

I was expecting the last bit to be different.

Adding 20 to 25
20 < 25
Left node of 25 exists 15
Adding 20 to 15
20 > 15
Right node of 15 does not exist
15
30

Can someone explain what is happening here?

Stephen Paulger
  • 5,204
  • 3
  • 28
  • 46
  • 2
    `left = &node;` - http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – chris Feb 04 '13 at 19:09
  • 1
    Better learn C first if you don't yet understand pointers, C++ has a few twists which **are** going to confuse you as a beginner. –  Feb 04 '13 at 19:09
  • Better still, avoid raw pointers completely and use modern C++ idioms. – juanchopanza Feb 04 '13 at 19:12

1 Answers1

3

You are copying the address of a copy of TreeNode, not the address of the TreeNode in main.
Take note of the commented out function calls, and read this: How to pass objects to functions in C++?

//Output with TreeNode node as arg
//Creating node with value: 25
//Creating node with value: 15
//Creating node with value: 30
//Creating node with value: 20
//Adding 15 to 25
//15 < 25
//Left node of 25 does not exist
//Adding 30 to 25
//30 > 25
//Right node of 25 does not exist
//Adding 20 to 25
//20 < 25
//Left node of 25 exists 20
//Adding 20 to 20
//20
//20

//Output with TreeNode & node as arg
//Creating node with value: 25
//Creating node with value: 15
//Creating node with value: 30
//Creating node with value: 20
//Adding 15 to 25
//15 < 25
//Left node of 25 does not exist
//Adding 30 to 25
//30 > 25
//Right node of 25 does not exist
//Adding 20 to 25
//20 < 25
//Left node of 25 exists 15
//Adding 20 to 15
//20 > 15
//Right node of 15 does not exist
//15
//30

#include <iostream>
using namespace std;


class TreeNode {
    public:
        TreeNode *left;
        TreeNode *right;
        int value;

        TreeNode(int _value);
        //void add_node(TreeNode  node);
        void add_node(TreeNode & node);
};

TreeNode::TreeNode(int _value) {
    left = 0;
    right = 0;
    value = _value;
    cout << "Creating node with value: " << value << endl;
}

//void TreeNode::add_node(TreeNode node) {
void TreeNode::add_node(TreeNode & node) {
    cout << "Adding " << node.value << " to " << value << endl;
    if (node.value < value) {
        cout << node.value << " < " << value << endl;
        if (left) {
            cout << "Left node of " << value << " exists " << left->value << endl;
            left->add_node(node);
        } else {
            cout << "Left node of " << value << " does not exist" << endl;
            left = &node;
        }
    }
    if (node.value > value) {
        cout << node.value << " > " << value << endl;
        if (right) {
            cout << "Right node of " << value << " exists " << right->value << endl;
            right->add_node(node);
        } else {
            cout << "Right node of " << value << " does not exist" << endl;
            right = &node;
        }
    }
}

int main ()
{
    TreeNode root(25);
    TreeNode n1(15);
    TreeNode n2(30);
    TreeNode n3(20);

    root.add_node(n1);
    root.add_node(n2);
    root.add_node(n3);

    cout << root.left->value << endl;
    cout << root.right->value << endl;

    return 0;
}
Community
  • 1
  • 1
David D
  • 1,571
  • 11
  • 12
  • While this could work, it's worth noting that in real software we don't normally build trees like that. We use *dynamic allocation* and pass *pointers to nodes* around. – n. m. could be an AI Feb 04 '13 at 19:24
  • 1
    Really? I normally add *elements* and let the tree handle the allocation and placement of nodes internally. – paddy Feb 04 '13 at 19:30
  • @n.m. If the data structure contains constant data, I'd consider constructing it this way. – David D Feb 04 '13 at 19:35
  • @DavidD thank you. The first sentence really says it all but the example is very helpful too. – Stephen Paulger Feb 04 '13 at 21:10
  • @n.m and paddy I considered both of the approaches you mentioned but as you probably suspect, this isn't "real software" it's just me messing about in order to learn. I'll do some reading on the terms you've mentioned. Thanks. – Stephen Paulger Feb 04 '13 at 21:13