www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Newbie question: Return a locally allocated variable

reply Fitz <fitz figmentengine.com> writes:
I expect the following code below to create 10 items with 10 
different addresses, instead they all have the same address?

import std.stdio;

class Bob {
}

void main()
{
     for (auto i = 0; i < 10; i++) {
         auto pBob = bobFactory();
         writefln("bob   %x\n", pBob);
     }
}

Bob *bobFactory() {
     Bob bob = new Bob;
     Bob *pBob = &bob;

     return pBob;
}
Sep 14 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 14 September 2020 at 16:29:11 UTC, Fitz wrote:
 I expect the following code below to create 10 items with 10 
 different addresses, instead they all have the same address?
You are taking the address of the local variable holding reference, not the reference itself.
 class Bob {
 }

 Bob *bobFactory() {
     Bob bob = new Bob;
     Bob *pBob = &bob;

     return pBob;
 }
This is a common mistake with people coming from C++. A D class is more like a Java class - it is automatically a reference. So your class Bob here in D would actually be represented as `Bob*` in C++. Thus when you define `Bob*` in D, that's like a `Bob**` in C++... a pointer to a pointer. Thus you're getting the address on the stack of the local, not at all what you want. Your factory should really just be: Bob bobFactory() { return new Bob; } Then to compare addresses, do: writeln(cast(void*) bob); // convert the reference itself to a pointer
Sep 14 2020
parent Fitz <fitz figmentengine.com> writes:
On Monday, 14 September 2020 at 16:44:14 UTC, Adam D. Ruppe wrote:

 This is a common mistake with people coming from C++. A D class 
 is more like a Java class - it is automatically a reference.

 So your class Bob here in D would actually be represented as 
 `Bob*` in C++.

 Thus when you define `Bob*` in D, that's like a `Bob**` in 
 C++... a pointer to a pointer. Thus you're getting the address 
 on the stack of the local, not at all what you want.

 Your factory should really just be:

 Bob bobFactory() { return new Bob; }

 Then to compare addresses, do:

 writeln(cast(void*) bob); // convert the reference itself to a 
 pointer
thank you! I was driving myself mad. makes sense now.
Sep 14 2020