February 03, 2018
Given the following code:

import std.stdio : writeln;

---
struct Foo
{
    Foo*[] children;
    void value()
    {
        Foo bar = Foo();
        version (bad1)
        {
            this.children ~= &bar;
        }
        version (bad2)
        {
            this.children.length += 1u;
            this.children[$-1] = &bar;
        }
    }
    void bark()
    {
        writeln("children: ", this.children.length);
        writeln("grandchildren: ", this.children[0].children.length);
    }
}

void main ()
{
    Foo foo = Foo();
    version (good)
    {
        Foo bar = Foo();
        foo.children ~= &bar;
    }
    else
    {
        foo.value();
    }
    foo.bark();
}
---

The resulting executable returns the following outputs:

C:\Users\Jonathan\Desktop\bug>dmd .\bug.d -version=bad1

C:\Users\Jonathan\Desktop\bug>bug.exe
children: 1
grandchildren: 4203068

C:\Users\Jonathan\Desktop\bug>dmd .\bug.d -version=bad2

C:\Users\Jonathan\Desktop\bug>bug.exe
children: 1
grandchildren: 1

C:\Users\Jonathan\Desktop\bug>dmd .\bug.d -version=good

C:\Users\Jonathan\Desktop\bug>bug.exe
children: 1
grandchildren: 0


Why?

February 04, 2018
For starters, this sort of question belongs in the Learn forum. Now to your problem.



> The resulting executable returns the following outputs:
>
> C:\Users\Jonathan\Desktop\bug>dmd .\bug.d -version=bad1
>
> C:\Users\Jonathan\Desktop\bug>bug.exe
> children: 1
> grandchildren: 4203068

Running at run.dlang.io:

children: 1
grandchildren: 10

>
> C:\Users\Jonathan\Desktop\bug>dmd .\bug.d -version=bad2
>
> C:\Users\Jonathan\Desktop\bug>bug.exe
> children: 1
> grandchildren: 1

children: 1
grandchildren: 140722524752048


>
> Why?

Because structs are value types and you're creating them on the stack. Anything created on the stack in a function will eventually be stomped after the function exits, but with structs you also have the fact that the instance is destroyed. You can see this by adding a destructor to your Foo type and sprinkling some writelns around:

======
import std.stdio : writeln;

struct Foo
{
    Foo*[] children;

    ~this() { writeln("Destroyed!"); }

    void value()
    {
        writeln("Entered value.");
        Foo bar = Foo();
        version (bad1)
        {
            this.children ~= &bar;
        }
        version (bad2)
        {
            this.children.length += 1u;
            this.children[$-1] = &bar;
        }
        writeln("Exiting 'value'");
    }
    void bark()
    {
        writeln("children: ", this.children.length);
        writeln("grandchildren: ", this.children[0].children.length);
    }
}

void main ()
{
    Foo foo = Foo();
    version (good)
    {
        Foo bar = Foo();
        foo.children ~= &bar;
    }
    else
    {
        writeln("Entering value.");
        foo.value();
        writeln("value exited.");
    }
    foo.bark();
    writeln("Exiting main");
}
=======

Running bad1 & bad2 will print something like this:

Entering value.
Entered value.
Exiting 'value'
Destroyed!
value exited.
children: 1
grandchildren: 10
Exiting main
Destroyed!

As you can see, the Foo instance created inside value will be destroyed when the function exits, so that by the time you call foo.bark, children[0] is no longer in a valid state -- hence the garbage value for children[0].children.length. If you want bar to persist outside of value, you need to allocate it on the heap:

Foo* bar = new Foo;
this.children ~= bar;