www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - Pointer to Array Element error?

reply collerblade <collerblade gmail.com> writes:
Hello guys,
Im using D llvm for my personal project, and i run into a strange 
behavior. My code is:

struct Node {
    string name;
    ...
    Node[] children;

    Node* search(in string nodeName) {
       if(name==nodeName)
          return &this;
       foreach(child;children) {
          auto r=child.search(nodeName);
          if(r)
             return r;
       }
       return null;
    }
}

Usually first i build the tree from Node-s. Then i seach the tree 
for nodes. It is pritty simple.
But today i run into a problem. The returned Node* from search 
function points to invalid data. Search code:

Node* result=root.search("whatever node name");
if(result) {
    writeln(result.name);
}

And this code crashes. The result.name.ptr points to some unknown 
data. But the result pointer has the same value as in the search 
function. This gives me headakes.
Complete code:

struct Node {
    string name;
    ...
    Node[] children;

    Node* search(in string nodeName) {
       if(name==nodeName) {
          writeln("returned node: ",&this," name: ",name); 
//0xABCDEF01 nodename
          return &this;
       }
       foreach(child;children) {
          auto r=child.search(nodeName);
          if(r)
             return r;
       }
       return null;
    }
}

Node* result=root.search("whatever node name");
writeln(result); //0xABCDEF01 //same pointer as before
writeln(result.name); //crashes result.name.ptr is random 
pointer, as anything else in the struct has random value

1. If i do a second search (for the same name), the result is the 
same pointer value, so data is there, and it isnt moved by 
anything.
2. If i search again (for the same name): the writeln() in the 
search function prints the correct name, so the memory of the 
struct is not been overwrited
3. If i search again (still for the same name) the 
result.name.ptr is incorrect  but the same as the first search 
value.
4. I use unly 1 thread. And Thread.getThis() is the same 
everywhere.

I dont know what the issue is here. Am i missing something?

Ty: collerblade
Jan 18 2016
next sibling parent collerblade <collerblade gmail.com> writes:
I forget 1 thing!

5. If i rewrite the struct to class. (And i return Node instead 
of Node* ofc). The code works perfectly!!!
Jan 18 2016
prev sibling parent reply Dragos Carp <dragoscarp gmail.com> writes:
On Monday, 18 January 2016 at 09:43:13 UTC, collerblade wrote:
....
 struct Node {
    string name;
    ...
    Node[] children;

    Node* search(in string nodeName) {
       if(name==nodeName) {
          writeln("returned node: ",&this," name: ",name); 
 //0xABCDEF01 nodename
          return &this;
       }
       foreach(child;children) {
The problem is here. In D the structs have value semantics, i.e. child is a stack allocated copy of the element in children and consequently an address on stack is returned. foreach (ref child, children) should solve your problem.
          auto r=child.search(nodeName);
          if(r)
             return r;
       }
       return null;
    }
 }
PS: this is a typical post for the learn forum
Jan 18 2016
parent collerblade <collerblade gmail.com> writes:
You are right. I miss that part.
Ty: collerblade
Jan 18 2016