Self-referential structs

Aug 19, 2018 at 4:09pm
Hello,

I have recently faced a problem of creating the self-referential structures. Whenever I try to use them, the program behaves weirdly. Take, for instance, the code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
struct N
{
    int value;
    N *left;
    N *right;
}N;
int main()
{
    N.value = 1;
    N.right->value = 2;
    N.right->right->value = 3;
    N.right->right->right->value = 4;
    cout<<N.right->right->right->value;
    return 0;
}

If anything, it seems to decide whether to output the given value without a coherent pattern that I would recognize. Why is that?
Aug 19, 2018 at 4:55pm
You're not doing it correctly. You can't dereference right (or left) with -> (or *) when the pointer hasn't been set to point to allocated memory. You need to allocate memory for the new nodes with the "new" operator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

struct N {
    int value;
    N *left;
    N *right;
};

int main() {
    N n;

    n.value = 1;

    n.right = new N;
    n.right->value = 2;

    n.right->right = new N;
    n.right->right->value = 3;

    n.right->right->right = new N;
    n.right->right->right->value = 4;

    std::cout << n.right->right->right->value << '\n';

    // We should probably be setting all the "left" pointers of the new nodes to null since they don't point to anything.
    // And we should usually "delete" the allocated memory, but we can leave that to the OS.
}

Or you could do something like this, using a constructor for the struct.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>

struct Node {
    int value;
    Node* left;
    Node* right;
    
    Node(int v, Node* lf=0, Node* rt=0) : value(v), left(lf), right(rt) {}
};

void print(const Node *nd) {
    if (!nd) return;
    print(nd->left);
    std::cout << nd->value << ' ';
    print(nd->right);
}

void deleteTree(Node *nd) {
    if (!nd) return;
    deleteTree(nd->left);
    deleteTree(nd->right);
    delete nd;
}

int main() {
    Node* root = 0;   // empty tree
    /* Create tree:
            5
        3       7
      1   4   6   9
    */
    root = new Node(5,
               new Node(3,
                   new Node(1), new Node(4)),
               new Node(7,
                   new Node(6), new Node(9)));

    print(root);
    std::cout << '\n';

    deleteTree(root);
}

Last edited on Aug 19, 2018 at 5:00pm
Aug 19, 2018 at 5:05pm
Thank you! Much appreciated.
Topic archived. No new replies allowed.